Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/58.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 为什么HeapFree之后仍然可以访问堆内存_C_Windows_Winapi_Heapalloc - Fatal编程技术网

C 为什么HeapFree之后仍然可以访问堆内存

C 为什么HeapFree之后仍然可以访问堆内存,c,windows,winapi,heapalloc,C,Windows,Winapi,Heapalloc,我写了一个简单的C程序,它创建了一个单链表。它起作用了;例如,我将一些数字压入一个列表,函数print\u list(…)将数字打印到控制台 然而,我随后添加了一个clear\u list(…)函数,并在print\u list(…)之前调用它,以查看会发生什么。调用清除列表后,打印列表仍像以前一样打印数字 print\u list如何从释放的内存中打印数字?我使用HeapAlloc分配列表结构,使用HeapFree取消分配 代码如下: 静态布尔推送列表(DWORD a) { 列表*ptr=NU

我写了一个简单的C程序,它创建了一个单链表。它起作用了;例如,我将一些数字压入一个列表,函数
print\u list(…)
将数字打印到控制台

然而,我随后添加了一个
clear\u list(…)
函数,并在
print\u list(…)
之前调用它,以查看会发生什么。调用
清除列表
后,
打印列表
仍像以前一样打印数字

print\u list
如何从释放的内存中打印数字?我使用
HeapAlloc
分配列表结构,使用
HeapFree
取消分配

代码如下:

静态布尔推送列表(DWORD a)
{
列表*ptr=NULL;
ptr=(PLIST)HeapAlloc(GetProcessHeap(),HEAP_ZERO_内存,sizeof(LIST));
如果(ptr==NULL)
{
printf(“错误推送列表”);
返回FALSE;
}
ptr->i=a;
ptr->next=列表头;
列表头=ptr;
返回TRUE;
}
无效自由目录列表(无效)
{
PLIST pTemp=NULL;
P_列表PTR=列表头;
while(PTR!=NULL)
{
pTemp=PTR;
PTR=PTR->next;
HeapFree(GetProcessHeap(),0,pTemp);
}
}

在C中,使用释放内存是未定义的行为


它在这里工作是因为在释放内存后,内存没有任何变化。通常在释放内存后立即出现这种情况。像
HeapFree(…)
或仅仅是标准的C
free(…)
这样的函数通常不会将内存归零;它们只是改变由运行时管理的内部状态,以便已知内存是空闲的

为什么在HeapFree之后不能访问内存?这不是虚拟自由。空闲后使用内存的任何方式都是UB。可以是此处的任何结果,请阅读以下内容:。这是关于局部变量超出范围的问题,但在free()之后,同样的推理也可以应用于堆变量。当您释放内存时,它不会在物理上消失。而且释放函数不会修改它释放的内存的数据。访问您不拥有的内存(如释放内存后)会导致未定义的行为。我说过这些不正确的内存访问是“未定义的行为”,而C中的未定义行为是一个有趣的概念。这意味着任何事情都可能发生。您可能会收到错误消息,但可能不会。它可能会做你期望的事情,但可能不会。它可能今天做一件事,明天做另一件事,您不会得到
NULL
响应,那么是的,您可以使用内存。如果在您呼叫
免费(buf)之后您不应该尝试使用它。(注意,您尝试分配的内存块越大,出现
NULL
响应的可能性就越高。)此外,请在上阅读此链接。