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

C++中new创建数组的delete[]问题:无原指针与重复释放解析

无法访问new[]数组的原指针时如何正确删除数组?

问题背景

当无法直接访问用new[]声明的数组的原指针(已知数组大小)时,该如何正确删除这个数组?以下是示例代码及出现的问题:

void enlarge(int * x) {
    int * tmp = new int[20];
    memcpy(tmp, x, 10*sizeof(int));
    delete[] x; //?
    x = tmp;
}

int main() {
    int * x = new int[10];
    enlarge(x);
    delete[] x; //??? free(): double free detected in tcache 2
}

疑问解答

1. enlarge函数内的delete[]是否知晓需释放的内存大小?

是的,delete[]完全清楚要释放的内存大小。C++在通过new[]分配数组内存时,会在内存块的头部(对用户不可见的区域)存储数组的元素数量或总内存大小信息,delete[]执行时会读取这个隐藏信息,从而准确释放整个数组的内存,不需要手动传入大小参数。只要你持有数组的首指针,delete[]就能正确完成释放。

2. main函数内的delete[]触发错误的原因是什么?该如何避免?

  • 错误原因:这是典型的**双重释放(double free)**问题。enlarge函数的参数x是按值传递的,函数内部对x的修改(x = tmp)只会改变函数内的局部变量,不会影响main函数里的原指针。也就是说,main中的x仍然指向最初用new[10]分配的内存,而这块内存已经在enlarge里被delete[] x释放过一次了,main里再次调用delete[] x就属于重复释放同一块内存,触发内存错误。

  • 解决方法:把enlarge的参数改为指针的引用,这样函数内部对x的修改会同步到main中的原指针。修改后的函数签名为void enlarge(int*& x),这样enlarge里的x = tmp会让main里的x指向新分配的数组,main中的delete[] x就会释放新数组,不会出现重复释放的问题。

修改后的完整代码:

void enlarge(int*& x) {
    int* tmp = new int[20];
    memcpy(tmp, x, 10 * sizeof(int));
    delete[] x;
    x = tmp;
}

int main() {
    int* x = new int[10];
    enlarge(x);
    delete[] x; // 正常释放,无错误
}

额外说明:如果真的遇到原指针丢失的情况(比如没有保存指针副本),那只能确保在指针丢失前已经用delete[]释放内存,否则会造成内存泄漏。你的示例问题本质是参数传递方式错误,并非真正无法访问原指针。

内容的提问来源于stack exchange,提问作者user1079505

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 06:10:11