为什么vector.size()-有些东西会导致分段错误?
在以下代码中,for循环不会运行(由于条件i<0-1),并且不会打印任何内容:
#include <iostream>
#include <vector>
using namespace std;
int main() {
for(int i=0; i < 0-1; i++){
cout<<"Yes"<<endl;
}
return 0;
}
但是当我执行以下操作时,矢量大小按预期打印为 0。所以for loop不应该打印任何东西,就像上面的例子一样。但实际上,这样的事情给了我错误,如分段错误或多次SIGKILL打印后Yes(在使用 C++ 14 gcc 6.3 的在线 ide 中):
#include <iostream>
#include <vector>
using namespace std;
int main() {
vector<int> a;
cout<<a.size()<<endl;
for(int i=0;i<a.size()-1;i++){
cout<<"Yes"<<endl;
}
return 0;
}
我注意到另一件事是,它按预期工作,如果我更换a.size() - 1只a.size()。
回答
a.size()返回一个无符号整数。当你从无符号 0 中减去 1 时,它下溢(查找“无符号整数下溢”到 0xFFFFFFFF(一个非常大的数字)。所以你的循环运行了很长时间。
事实上,因为所有可能的ints为小于0xFFFFFFFF的编译器是足够聪明,知道i<a.size()-1将永远是真实的,它只是变成循环陷入死循环。
您可以在 Godbolt 上验证此行为。
以下代码:
#include <vector>
using namespace std;
void foo() {
vector<int> a;
for(int i=0;i<a.size()-1;i++){
asm("");
}
}
编译到这个程序集:
foo(): # @foo()
.LBB0_1: # =>This Inner Loop Header: Depth=1
jmp .LBB0_1
这只是一个无限循环。这asm("")是一些魔术,以便编译器不会删除循环体。