C++ C/C++;破坏调用堆栈的代码

C++ C/C++;破坏调用堆栈的代码,c++,callstack,C++,Callstack,在c/c++中,是否可能有一个常见的代码损坏调用堆栈? 我不是指一种黑客或什么,只是一个疏忽错误或什么,但不是随机的,以至于每次都会损坏它。 有人告诉我一位前同事成功了,但我认为这是不可能的。 有人有这样的经历吗?是的,很简单。事实上,这是一个非常普遍的问题。考虑这一点: void foo() { int i; int *p = &i; p -= 5; // now point somewhere god knows where, generally undefi

在c/c++中,是否可能有一个常见的代码损坏调用堆栈? 我不是指一种黑客或什么,只是一个疏忽错误或什么,但不是随机的,以至于每次都会损坏它。 有人告诉我一位前同事成功了,但我认为这是不可能的。
有人有这样的经历吗?

是的,很简单。事实上,这是一个非常普遍的问题。考虑这一点:

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
}

在许多情况下,对本地阵列/缓冲区进行越界访问最终会导致堆栈损坏。

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

void evil() {
    int array[1];
    std::fill(array, array+1000000, 0);
    return; // BOOM!
}
更微妙的是,返回对局部变量的引用可能会损坏稍后调用的函数堆栈:

int & evil() {
    int x;
    return x;
}
void good(int & x) {
    x = 0;
    return; // BOOM!
}
void innocent() {
    good(evil());
}

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

而c变体my be作为链接器会发现double evil(双a)。。。file1.h
double-evil(双a)
file1.c#include“file1.h”双恶(double-a){返回a*5;}`main.c#include
double-evil(void)//仅声明
intmain(void){printf(“结果是%f,\n”,evil());//BOOM return 0;}在C/C++中很容易损坏调用堆栈。这就是许多人恨他们的原因。