我有以下代码。
#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();
}
在这里,我要限制数组的范围,但是仍然继续。 它从来没有发生过。我不能说这里出什么问题了吗?
答案 0 :(得分:6)
第二个p->d=10;
的行为是未定义。不崩溃是这种不确定行为的体现。 (您可能会发现,free
实际上并没有在特定情况下将内存还给操作系统。)
a[5]=100;
也未定义。同样,您可能会发现C ++运行时库/操作系统分配的内存超过3个int
。
尽管有(1)和(2),您的程序仍未定义,因为您需要使用int main()
。同样,允许与int main()
一致的编译和运行时行为是未定义行为的体现。
答案 1 :(得分:1)
术语:堆栈和堆不同。
堆栈用于静态内存分配:char foo [100];
堆用于动态内存分配:char * foo = malloc(100);
自从我使用可视化C ++已有几年了。我似乎记得它有编译功能,也许还有链接时间选项,可以检查内存问题。
在运行时,C / C ++运行时系统从操作系统请求内存,它以大块的形式获取内存,然后C / C ++运行时代码根据需要对其进行切片。当您跳出该块时,可能会遇到运行时错误。您可能会随机得到其他错误。
当function2()正确使用了function1()已损坏的那部分内存时,由于损坏了堆栈或堆,您可能会遇到奇怪的运行时错误。如果程序的其他部分都没有使用损坏的相同内存,则很可能看不到任何错误。您的代码仍然存在该错误,但是直到代码的另一部分或C / C ++运行时注意到您踩到了它的变量时,该错误才会出现。