You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.08 18:30:03