问题似乎是“* p = 20;”命令,虽然我根本就不明白为什么。每当我添加它时,我都会收到错误“变量'var'周围的堆栈已损坏”。
main(void)
{
int* p;
int var;
p = &var;
*p = 16;
p++;
*p = 20;
system("pause");
}
答案 0 :(得分:2)
在此声明之后
p
指针var
未指向有效对象(它现在指向类型为int
的对象*p = 20;
之外的内存。因此这句话
{{1}}
导致未定义的行为。那是
围绕变量' var'被腐蚀了
答案 1 :(得分:0)
您收到此错误的原因是因为您覆盖了来自莫斯科的Vlad向您展示的堆栈上受保护的内存。编译器将保护您免受堆栈损坏。有多种方法可以实现这一点,但一种方法是使用" canary,"这只是特定内存位置的一个或多个值。如果这些值发生了变化,编译器会知道堆栈已损坏,并且可能会给出一个错误消息,例如"堆栈变量' var'已经腐败了。"在您的情况下,超出变量var的4个字节的内存位置可能是堆栈上的一个金丝雀值(如果您的特定漫游器使用了金丝雀),您更改了该值并导致错误。
有关详细信息,请参阅buffer overflow protection上的维基百科文章。
这是摘自文章的摘录:
通常,缓冲区溢出保护会修改堆栈分配数据的组织,因此它包含一个canary值,当堆栈缓冲区溢出时,它会显示内存中的缓冲区溢出。通过验证金丝雀值,可以终止受影响程序的执行,防止其行为不端或允许攻击者控制它。其他缓冲区溢出保护技术包括边界检查,它检查对每个分配的内存块的访问,使它们不能超出实际分配的空间,以及标记,这确保分配用于存储数据的内存不能包含可执行代码。
编辑:
我其实非常喜欢wiki文章中的下一段:
在堆栈上分配的缓冲区溢出更有可能影响程序执行,而不是溢出堆上的缓冲区,因为堆栈包含所有活动函数调用的返回地址。但是,对于基于堆的溢出,也存在类似的特定于实现的保护。