delete[] arr 和在循环中删除元素有啥区别[重复]

Posted

技术标签:

【中文标题】delete[] arr 和在循环中删除元素有啥区别[重复]【英文标题】:What's the difference between delete[] arr and deleting elements in a loop [duplicate]delete[] arr 和在循环中删除元素有什么区别[重复] 【发布时间】:2014-07-15 19:39:53 【问题描述】:

上下文: 我需要将所有元素从一个数组移动到一个新数组。复制后旧数组将被销毁。

代码:

int* array = new int[5];
int* newArray = new int[5];

选项1:销毁循环中的元素

for (int i = 0; i < 5; ++i) 
  newArray[i] = array[i];
  delete (array + i);

选项 2:使用 delete[]

for (int i = 0; i < 5; ++i) 
  newArray[i] = array[i];

delete[] array;

问题: 有什么不同? delete[] 是否比 option1 更有效(delete[] 会破坏内存块而不是逐个元素地擦除吗?)?

【问题讨论】:

【参考方案1】:

好吧,选项 1 表现出未定义的行为,因此区别在于正确代码和错误代码之一。

您只能delete(或者,在本例中为delete[])从new 返回的内容。数组的各个元素不是由 new 返回的(也不是指针)。在 new 未返回的指针上调用 delete,即 array + n 会调用未定义的行为。

new 的实现分配的内存可能比簿记请求的内存要多。它得到一个指针p,然后说“好的,现在让我们看看在p - sizeof(some_structure) 为我创建的信息new。现在我知道我分配了n 字节的内存,因为some_structure.n 告诉我所以,所以我现在就把它清理干净”。

当它试图在你给它的错误指针上这样做时,它会读取废话并且任何事情都可能发生。


附带说明,更喜欢 std::copy 复制数组,而不是循环。

【讨论】:

嗨,埃德。我明白你的意思了!现在我很好奇“new int[3]”是否等于“new int();new int();new int();”?这些动态创建的整数是否存储在堆内存而不是堆栈中? @lichgo:规范没有提到“堆”或“堆栈”,因为它们是实现细节,但是是的,在我知道的每个实现中,它都会动态分配在堆结构上(与位于堆栈上的具有自动存储持续时间的变量相反。)new int() 返回一个指向单个int 的指针,您可以使用delete p 释放它。 new int[n] 返回一个指向 n ints 的指针,然后用 delete [] p 删除它。规则是;如果您使用new [],那么您可以免费使用delete []。否则,您使用delete,而您只使用delete new 返回的内容。 @lichgo 你的前提是错误的。这些东西是不等价的。无论如何,实现将东西存储在哪里取决于它;作为语言客户,您唯一关心的是它可以(并且确实如此)。 "new 和 delete 几乎肯定会分配更多" - new[] 通常是这样,因为它需要跟踪元素的数量,因此 delete[] 可以迭代调用析构函数,但是对于“普通”new,许多实现将具有一组小的固定大小区域(例如 8 字节容量),并且该区域大小内的任何指针都是隐式已知的,对于其他区域,可以在分配区域之外跟踪大小(例如在不同的空闲列表/树中)。【参考方案2】:

deletedelete[] 根本不同(一个不能替代另一个)。

delete a 释放a 指向的内存。

 a
 |
 v
 Abcde

delete[]a 开始释放数组的内存。

 a
 |
 v
 AbcdeAbcdeAbcdeAbcde

第一个不是数组;第二个是数组。

【讨论】:

以上是关于delete[] arr 和在循环中删除元素有啥区别[重复]的主要内容,如果未能解决你的问题,请参考以下文章

循环删除数组中元素的正确方法

js 数组遍历时删除元素

怎样删除js数组中的undefined?

java操作数据库时在while循环里面new一个对象和在while循环外面new一个对象有啥区别?

java数组如何循环添加元素

truncate和delete有啥区别