C堆栈和堆损坏
我最近在阅读有关堆栈和附件的内容. C& C中的堆腐败C .该网站的作者使用以下示例演示了堆栈损坏.
#include<stdio.h> int main(void) { int b = 10; int a[3]; a[0] = 1; a[1] = 2; a[2] = 3; printf(" b = %d n",b); a[3] = 12; // oops it is invalid,behaviour is undefined printf(" b = %d n",b); printf("address of b= %xn",&b); printf("address of a[3]= %xn",&a[3]); return 0; } 我在visual studio 2010编译器(VC)上测试了以上程序&它给了我运行时错误,说:
现在我的问题是:堆栈是否已终生损坏,或者仅在上述错误程序执行期间? 同样,我知道两次删除相同的指针可能会造成堆损坏等非常糟糕的事情. int* p=new int(); delete p; delete p; // oops disaster here,undefined behaviour 当上面的代码片段执行时,VC在运行时显示堆损坏错误. 解决方法
你必须小心这里的术语.堆栈是否会在程序的剩余时间内“损坏”?它可能是;它可能不是.在这种情况下,您只会损坏当前堆栈帧中的数据,因此一旦您退出该函数调用,实际上您的“损坏”将会消失.
但这并非完整的故事.既然你已经覆盖了一个不应该存在的字节变量,你的程序会产生什么样的连锁效应呢?如果您通过网络连接发送此数据并且数据不再是预期的形式,则此内存损坏的后果可能会在逻辑上传递到其他功能范围,甚至其他计算机. (通常,您的数据协议将内置安全功能,以检测和丢弃意外形式的数据;但是,这取决于您.) 堆损坏也是如此.每当你覆盖不应该被覆盖的东西的字节时,并且任何时候你使用任意或不可知的数据这样做,你就会冒着潜在的灾难性后果,这可能在逻辑上持续超出程序的生命周期. 在作为语言的C的范围内,此条件总结为特定短语:未定义的行为.它表明,在你破坏了你的记忆后,你根本不能真正依赖任何东西.一旦你调用了UB,所有的赌注都会被取消. 您通常在实践中保证的一个保证是您的操作系统不允许您直接覆盖任何不属于您的程序的内存.也就是说,破坏其他进程或操作系统本身的内存非常困难.现代操作系统的内存模型是故意设计的,以便保持程序隔离并防止破坏的程序和/或病毒造成这种损害. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |