如果我无法访问原始指针 x,如何删除用
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
}
delete[]
在enlarge()
函数中会知道要释放多少内存吗?delete[]
内的main()
会导致执行时出错。为什么?如何避免?delete
中的 enlarge
调用删除了 int *x
中声明的 main
,因为您只是将指针传递给新函数。这就是为什么delete[] x
在main
给你双倍免费的原因;该指针不再存在。
更新:我应该澄清一下,当您按值传递指针时,实际上是在复制它。
delete
指针的副本也 delete
是原始指针。
如果我无法访问原始指针 x,如何删除用 new 声明的数组?
你不能。为了删除动态数组,您必须知道指向该数组第一个元素的指针 - 即
new
. 返回的指针
enlarge() 函数中的 delete[] 知道要释放多少内存吗?
是的。
显然,main() 中的 delete[] 会导致执行期间出错。为什么?
因为同一个指针已经在
enlarge
中被删除了。如果你多次删除一个指针,程序的行为是未定义的。
如何避免?
不要多次删除指针。
附言
enlarge
泄漏了它分配的数组。
函数
enlarge
产生内存泄漏,因为在main中声明的指针x
是按值传递给函数的。那就是函数处理原始指针x
值的副本。在函数内更改副本会使在 main 中声明的原始指针x
保持不变。
因此 main 中的这个语句
delete[] x;
调用未定义的行为,因为指针
x
指向的内存已经在函数enlarge
中被释放。
你需要像这样通过引用传递指针
void enlarge(int * &x) {
int * tmp = new int[20];
memcpy(tmp, x, 10*sizeof(int));
delete[] x;
x = tmp;
}
注意,最好使用标准容器而不是原始指针
std::vector
.