C语言双指针操作动态数组时指针置空、free触发双重释放问题咨询
核心问题解答
1. 为什么pArray设为NULL后*ppArray仍保留原有值
指针本质是存储内存地址的普通变量,你在代码中执行*ppArray = pArray时,是把pArray变量中存储的堆内存首地址值复制给了*ppArray(也就是main函数中的pIntegerArray变量)。
这两个是完全独立的指针变量,只是临时存储了相同的地址值而已。后续将局部变量pArray设为NULL,仅修改了pArray自身存储的内容,既不会改变已经复制给*ppArray的地址值,也不会改动该地址指向的堆内存数据,所以*ppArray自然可以正常访问数组内容。
2. 为什么调用free(pArray)会触发double free报错
free()函数的作用是释放指针指向的堆内存空间,而非删除指针变量本身。
如果你在fillArray中执行free(pArray),此时pArray和*ppArray指向的是同一片堆内存,这一步已经把这片内存释放回系统了。等main函数末尾执行free(pIntegerArray)时,相当于再次尝试释放同一块已经被释放的内存,就会触发double free的错误。
你后续将pArray设为NULL的操作,仅清空了pArray这个局部变量的存储值,既不能撤销已经释放内存的操作,也不会修改main中pIntegerArray存储的无效地址,因此完全避免不了重复释放的问题。
补充注意点
- 堆内存的生命周期和指向它的指针变量无关,只要没有主动调用
free,即使指向它的局部指针被修改、甚至被销毁,内存也会一直保留。 - 仅对指向某片内存的单个指针设NULL,只会避免该指针被重复free,其他指向同一片内存的指针不会被自动修改,仍会变成野指针。
// 示例代码 #include <stdio.h> void fillArray(int **ppArray, int *pArraySize){ int *pArray = NULL; int *pTmp; int arraySize = 0; for(int i = 0; i < 5; i++) { pTmp = realloc(pArray,(arraySize+1) * sizeof(int)); pArray = pTmp; pArray[arraySize] = i; arraySize += 1; } *ppArray = pArray; *pArraySize = arraySize; // 此处如果执行free(pArray)会直接释放堆内存,后续main中的pIntegerArray就变成野指针 pArray = NULL; } int main() { int *pIntegerArray; int arraySize; fillArray(&pIntegerArray,&arraySize); for(int i = 0; i < 5; i++) { printf(" %u", pIntegerArray[i]); } free(pIntegerArray); return 0; }
内容的提问来源于stack exchange,提问作者Hani Daher- Reinstate Monica
相关产品推荐
相关产品推荐

