变量'var'周围的堆栈已损坏

时间:2017-05-12 18:23:31

标签: c pointers

问题似乎是“* p = 20;”命令,虽然我根本就不明白为什么。每当我添加它时,我都会收到错误“变量'var'周围的堆栈已损坏”。

main(void)
{
    int* p;
    int var;
    p = &var;
    *p = 16;    
    p++;        
    *p = 20;    
    system("pause");
}

2 个答案:

答案 0 :(得分:2)

在此声明之后

p

指针var未指向有效对象(它现在指向类型为int的对象*p = 20; 之外的内存。因此这句话

{{1}}

导致未定义的行为。那是

  

围绕变量' var'被腐蚀了

答案 1 :(得分:0)

来自莫斯科的弗拉德的回答是正确的。这里有一些关于我认为有用的原因的其他信息。

您收到此错误的原因是因为您覆盖了来自莫斯科的Vlad向您展示的堆栈上受保护的内存。编译器将保护您免受堆栈损坏。有多种方法可以实现这一点,但一种方法是使用" canary,"这只是特定内存位置的一个或多个值。如果这些值发生了变化,编译器会知道堆栈已损坏,并且可能会给出一个错误消息,例如"堆栈变量' var'已经腐败了。"在您的情况下,超出变量var的4个字节的内存位置可能是堆栈上的一个金丝雀值(如果您的特定漫游器使用了金丝雀),您更改了该值并导致错误。

有关详细信息,请参阅buffer overflow protection上的维基百科文章。

这是摘自文章的摘录:

  

通常,缓冲区溢出保护会修改堆栈分配数据的组织,因此它包含一个canary值,当堆栈缓冲区溢出时,它会显示内存中的缓冲区溢出。通过验证金丝雀值,可以终止受影响程序的执行,防止其行为不端或允许攻击者控制它。其他缓冲区溢出保护技术包括边界检查,它检查对每个分配的内存块的访问,使它们不能超出实际分配的空间,以及标记,这确保分配用于存储数据的内存不能包含可执行代码。

编辑:

我其实非常喜欢wiki文章中的下一段:

  

在堆栈上分配的缓冲区溢出更有可能影响程序执行,而不是溢出堆上的缓冲区,因为堆栈包含所有活动函数调用的返回地址。但是,对于基于堆的溢出,也存在类似的特定于实现的保护。