为什么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() - 1a.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("")是一些魔术,以便编译器不会删除循环体。


以上是为什么vector.size()-有些东西会导致分段错误?的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>