我有一些麻烦要理解c ++程序的执行顺序。我有一个缓冲区溢出程序。但奇怪的是,segfault(由于缓冲区溢出)在代码中发生在缓冲区溢出之前的某些行。
我的计划如下:
//Some code ...
file.seekg(0, std::ios::end);
auto file_size = file.tellg();
file.seekg(0);
std::vector<uint8_t> buffer(file_size);
//Some code
char t[1];
t[2] = 1;
//Some code
因此,做法t[2] = 1
会生成缓冲区溢出。但是,在向量初始化期间发生了段错误。 file_size
计算得很好,但执行std::vector<uint8_t> buffer(file_size)
时,file_size
变为-1(生成段错误)。此段错误由缓冲区溢出生成。如果我删除了t[2] = 1
语句,则每个语句都可以正常运行。
所以我的问题是在执行缓冲区溢出之前如何发生段错误?代码的执行可以由编译器改变吗?
答案 0 :(得分:3)
所以我的问题是在执行缓冲区溢出之前如何发生段错误?代码的执行可以由编译器改变吗?
编译器可以自由重新排列堆栈中不相关数据的初始化。向量和数组之间没有逻辑关系,因此如果选择,编译器可以决定重新排序初始化。
但是你通过溢出数组边界来调用未定义的行为。这意味着您违反了编译器关于如何重新排序内存或代码的任何假设。所以现在所有的赌注都已关闭。任何事情都可能发生,即使它没有意义。