我有以下代码。。
#include "stdafx.h"
#include <stdlib.h>
#include <conio.h>
struct data
{
int d;
};
void main()
{
data *p=(data*)malloc(sizeof(data));
p->d=10;
free(p);
p->d=10;
_getch();
}
我预计在运行代码时会出现堆栈损坏错误,但Visual studio什么也没激发。。。即使在释放p…之后
它必须触发对未引用指针进行计数的错误。。。但它仍然在继续阅读和写作。。。为什么会发生这种情况,我有以下代码。。
int a[]={1,2,3};
void main()
{
a[5]=100;
_getch();
}
在这里,我的数组超出了界限,但它仍在继续。。它以前从未发生过。我不能说这里出了什么问题?
-
第二个
p->d=10;
的行为是未定义的。没有崩溃是这种未定义行为的表现。(您可能会发现,在您的特定情况下,free
实际上并没有将内存返还给操作系统。) -
a[5]=100;
也未定义。同样,您可能会发现C++运行库/操作系统分配的内存超过了3个int
s。 -
尽管有(1)和(2)的规定,您的程序是未定义的,因为您需要使用
int main()
。同样,允许编译和运行时行为与int main()
一致是未定义行为的表现。
术语:STACK和HEAP不是一回事。
堆栈用于静态内存分配:char foo[100];
堆用于动态内存分配:char*foo=malloc(100);
我使用visual C++已经有几年了。我似乎记得它有编译和链接时间选项来检查内存问题。
在运行时,C/C++运行时系统向操作系统请求内存,它以大块的形式获取内存,然后C/C++运行库代码根据需要对其进行切片。当您走出该块时,可能会出现运行时错误。您可能会随机出现其他错误。
当function2()正确使用了function1()损坏的内存块部分时,您可能会在损坏堆栈或堆时出现奇怪的运行时错误。当你的程序没有其他部分使用你损坏的内存时,你很可能不会看到任何错误。您的代码仍然有这个错误,但是直到代码的另一部分或C/C++运行时注意到您踩到了它的变量,它才会出现。