代码之家  ›  专栏  ›  技术社区  ›  Naveen

C++中的堆栈损坏

  •  18
  • Naveen  · 技术社区  · 15 年前

    6 回复  |  直到 15 年前
        1
  •  34
  •   Douglas Leeder    15 年前
    1. 您可以有一个随机/未定义的指针,它最终指向堆栈,并进行写入。
    2. 汇编函数可能会错误地设置/修改/恢复堆栈
    3. 宇宙波可以翻转堆栈中的位。
    4. 芯片外壳中的放射性元素可能会翻转钻头。
    5. 内核中的任何内容都可能出错并意外更改堆栈内存。

        2
  •  33
  •   Aadishri Raj    8 年前

    违反一个定义规则可能导致堆栈损坏。下面的示例看起来很愚蠢,但我已经在不同配置中编译的不同库中见过几次了。

    标题.h

    struct MyStruct
    {
       int val;
    #ifdef LARGEMYSTRUCT
       char padding[16];
    #endif
    }
    

    file1.cpp

    #define LARGEMYSTRUCT
    #include "header.h"
    
    //Here it looks like MyStruct is 20 bytes in size    
    
    void func(MyStruct s)
    {
       memset(s.padding, 0, 16); //corrupts the stack as below file2.cpp does not have LARGEMYSTRUCT declared and declares Mystruct with 4 bytes
       return; //Will probably crash here as the return pointer has been overwritten
    }
    

    file2.cpp

    #include "header.h"
    //Here it looks like MyStruct is only 4 bytes in size.
    extern void func(MyStruct s);
    
    void caller()
    {
       MyStruct s;
       func(s); //push four bytes on to the stack
    }
    
        3
  •  15
  •   Jimmy J    15 年前

    使用指向堆栈变量的指针是一种好方法:

    void foo()
    {
      my_struct s;
      bar(&s);
    }
    

    如果bar保留指针的副本,那么将来可能会发生任何事情。

    总结:当指针指向堆栈时,就会发生堆栈损坏。

        4
  •  9
  •   dirkgently    15 年前

    C++标准不定义堆栈/堆。此外,有许多方法可以调用程序中未定义的行为——所有这些都可能损坏堆栈(毕竟是UB)。简而言之,你的问题太模糊了,没有一个有意义的答案。

        5
  •  5
  •   peterchen    15 年前

    使用错误的调用约定调用函数。

        6
  •  4
  •   daramarak    15 年前

    在析构函数中抛出异常是一个很好的选择。这会使堆栈的展开变得混乱。