提问人:user1079505 提问时间:5/8/2023 最后编辑:Vlad from Moscowuser1079505 更新时间:5/8/2023 访问量:102
如何删除[]衰减的数组?[复制]
How to delete[] decayed array? [duplicate]
问:
如果我无权访问原始指针 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()
- 显然,within 会导致在执行过程中出现错误。为什么?如何避免?
delete[]
main()
答:
其中的调用正在删除声明的 ,因为您只是将指针传递给新函数。这就是为什么在给你一个双倍免费;该指针不再存在。delete
enlarge
int *x
main
delete[] x
main
更新:我应该澄清一下,当你按值传递指针时,你实际上是在复制它。指针的副本也是原始指针。delete
delete
该函数会产生内存泄漏,因为在 main 中声明的指针是按值传递给函数的。也就是说,该函数处理原始指针值的副本。在函数中更改副本时,将保持在 main 中声明的原始指针不变。enlarge
x
x
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
如果我无法访问原始指针 x,如何删除用 new 声明的数组?
你不能。为了删除动态数组,您必须知道指向该数组的第一个元素的指针,即 返回的指针。new
enlarge() 函数中的 delete[] 会知道要释放多少内存吗?
是的。
显然,main() 中的 delete[] 在执行过程中会导致错误。为什么?
因为相同的指针已经在 中删除了。如果多次删除指针,则程序的行为是未定义的。enlarge
如何避免?
不要多次删除指针。
P.S. 泄漏了它分配的数组。不要使用 new 和 delete。请改用 RAII 容器。enlarge
std::vector
啊,所以数组衰减只影响静态声明的数组
数组衰减是将数组类型的表达式隐式转换为指向第一个元素的指针。的类型是 。这不是数组类型。 是指针类型。由于它不是数组类型,因此它不会隐式转换为指向第一个元素的指针。 已经是指向第一个元素的指针。x
int*
int*
x
评论
delete[]
下一个:什么是三法则?
评论
enlarge
应该返回一个新指针,然后可以调用为 .否则,您将删除旧内存并泄漏新内存。调用方也无法再访问。更好的是,帮自己一个忙并使用x = enlarge(x)
std::vector<int>
void enlarge(std::unique_ptr<int[]> & x) { auto tmp = std::make_unique<int[]>(20); memcpy(tmp.get(), x, 10 * sizeof(int)); x = std::move(tmp); }
int main() {auto x = std::make_unique<int[]>(10); enlarge(x);}
x
void enlarge(int * x) {
x
x
int main()
int main()
int x[10]
?” -- 不准确。仅当对象类型为数组时,才会发生数组衰减。如果声明,则 的类型为数组。如果声明,则 的类型为指针。指针不能受到从数组到指针的衰减的影响,因为 1) 指针不是数组,并且 2) 指针已经是指针。int x[10]
x
int * x
x