损坏调用堆栈的C/C++代码

Nic*_*ova 3 c++ callstack

是否有可能通常的代码在c/c ++中损坏调用堆栈?我不是指某种黑客或某种东西,只是一种疏忽的错误或其他东西,而不是随意的,这样每次都会损害它.有人告诉我,一位前同事管理但我不认为这是可能的.有人有这样的经历吗?

lit*_*adv 6

是的,很容易.事实上,这是一个非常常见的问题.考虑一下:

void foo()
{
    int i;
    int *p = &i;
    p -= 5; // now point somewhere god knows where, generally undefined behavior
    *p = 0; // boom, on different compilers will end up with various bad things,
       // including potentially trashing the call stack
}
Run Code Online (Sandbox Code Playgroud)

许多本地数组/缓冲区的超出边界访问的情况最终都是被破坏的堆栈.


Mik*_*our 6

是.在许多平台上,局部变量与调用堆栈一起存储; 在这种情况下,在本地数组外写一个很容易破坏它的方法:

void evil() {
    int array[1];
    std::fill(array, array+1000000, 0);
    return; // BOOM!
}
Run Code Online (Sandbox Code Playgroud)

更巧妙的是,返回对局部变量的引用可能会破坏稍后调用的函数的堆栈:

int & evil() {
    int x;
    return x;
}
void good(int & x) {
    x = 0;
    return; // BOOM!
}
void innocent() {
    good(evil());
}
Run Code Online (Sandbox Code Playgroud)

请注意,这些(以及其他任何可能破坏堆栈的东西)都不合法; 但编译器不必诊断它们.幸运的是,只要您启用适当的警告,大多数编译器都会发现这些错误.