C++基础--指针 野指针和free
野指针的重复释放问题
最近发现了这样一个问题,一个指针释放两次之后,若在中间不置空,会报Invalid address specified to RtlValidateHeap 无效的堆地址 错误。
#include <iostream>
#include <string>
#include <malloc.h>
using namespace std;
int main() {
int* p = (int*)malloc(100);
free(p);
free(p);
}
想搞清楚为什么发生这种错误,首先得先搞清楚free()做了什么:
#include <iostream>
using namespace std;
int main() {
int *p = (int*)malloc(100);
printf("释放前p的地址%p\n",p);
free(p);
printf("释放后p的地址%p\n",p);
/**结果为:
释放前p的地址00000000006ffe14
释放后p的地址00000000006ffe14
**/
}
从代码中可以看到,free()前后p的值实际上是没有变化的,也就是说,p并没有置为空。
若此时加入该语句:
char x = *p;
则会触发程序断点Invalid address specified to RtlValidateHeap 无效的堆地址
然而明明p是有指向的,为什么会是无效的堆地址呢?
原因就是free()函数只是告诉了操作系统,这块内存我不再使用了,操作系统可以将该块内存重新分配了。
回到原有问题,当p被free()过一次之后,它实际上就成为了一个野指针,指向一个操作系统所保护的区域,这个区域将在未来可能被其他的指针指向。因此,我们第二次free(p)的时候,它实际上就是在操作一个可能已经其他模块用到的空间了,这时,也就出发了Invalid address specified to RtlValidateHeap 。