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
int
s 的指针,然后用 delete [] p
删除它。规则是;如果您使用new []
,那么您可以免费使用delete []
。否则,您使用delete
,而您只使用delete
new
返回的内容。
@lichgo 你的前提是错误的。这些东西是不等价的。无论如何,实现将东西存储在哪里取决于它;作为语言客户,您唯一关心的是它可以(并且确实如此)。
"new 和 delete 几乎肯定会分配更多" - new[]
通常是这样,因为它需要跟踪元素的数量,因此 delete[]
可以迭代调用析构函数,但是对于“普通”new
,许多实现将具有一组小的固定大小区域(例如 8 字节容量),并且该区域大小内的任何指针都是隐式已知的,对于其他区域,可以在分配区域之外跟踪大小(例如在不同的空闲列表/树中)。【参考方案2】:
delete
和 delete[]
根本不同(一个不能替代另一个)。
delete a
释放a
指向的内存。
a
|
v
Abcde
delete[]
从a
开始释放数组的内存。
a
|
v
AbcdeAbcdeAbcdeAbcde
第一个不是数组;第二个是数组。
【讨论】:
以上是关于delete[] arr 和在循环中删除元素有啥区别[重复]的主要内容,如果未能解决你的问题,请参考以下文章