为什么调用“删除”会发生错误?以特定方式在动态数组上不起作用?
我想知道为什么这段代码不起作用:
void KeyValueList::Release()
{
//(m_ppKeyValueList is a dynamic array of pointers to objects on the heap)
if (m_ppKeyValueList) {
for (int i = 0; i < m_iCapacity; ++i) {
if (m_ppKeyValueList[i]) {
delete m_ppKeyValueList[i];
}
}
/*delete[] m_ppKeyValueList;*/
for (int i = 0; i < m_iCapacity; ++i) {
delete (m_ppKeyValueList + i);
}
}
}
为什么我们不能迭代动态数组并以这种方式删除
它?
I'm wondering why this code doesn't work:
void KeyValueList::Release()
{
//(m_ppKeyValueList is a dynamic array of pointers to objects on the heap)
if (m_ppKeyValueList) {
for (int i = 0; i < m_iCapacity; ++i) {
if (m_ppKeyValueList[i]) {
delete m_ppKeyValueList[i];
}
}
/*delete[] m_ppKeyValueList;*/
for (int i = 0; i < m_iCapacity; ++i) {
delete (m_ppKeyValueList + i);
}
}
}
Why can't we iterate the dynamic array and delete
it in this way?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
情况 1:
m_ppKeyValueList
是“指向堆上对象的指针的动态数组”在这种情况下,您确实需要一块一块地删除m_ppKeyValueList。如果这就是您的意思,您的声明将采用以下形式
SomeType ** m_ppKeyValueList;
您的分配和释放应该类似于Allocation:
Deallocation:
但是,您的代码失败表明您没有“指向堆上对象的动态指针数组。”
情况 2:
m_ppKeyValueList
是堆上的动态对象数组在这里,您的声明将采用
SomeType * m_ppKeyValueList;
的形式,而不是逐段分配,您的分配和释放采用更简单的形式:分配:
释放:
底线 :
您的分配和释放需要在数量和形式上相互匹配。如果您使用
new
分配某些内容,则需要使用delete
销毁它。如果您使用new[]
分配它,则需要使用delete[]
销毁它。Case 1:
m_ppKeyValueList
is "a dynamic array of pointers to objects on the heap"In this case you do need to delete m_ppKeyValueList piece by piece. If this is what you meant, your declaration will be of the form
SomeType ** m_ppKeyValueList;
Your allocation and deallocation should likeAllocation:
Deallocation:
However, that your code fails suggests that you do not have "a dynamic array of pointers to objects on the heap."
Case 2:
m_ppKeyValueList
is a dynamic array of objects on the heapHere your declaration will be of the form
SomeType * m_ppKeyValueList;
Instead of allocating this piece by piece your allocation and deallocation take on a much simpler form:Allocation:
Deallocation:
Bottom line:
Your allocations and deallocations need to match one another in number and in form. If you allocate something with
new
you need to destroy it withdelete
. If you allocate it withnew[]
you need to destroy it withdelete[]
.动态数组不仅仅是元素序列。它还包含有关数组大小的信息。此外,分配器只知道一个内存块。因此,就像任何动态内存一样,您只能释放分配的内容,而不能释放其较小的子集。
这就是为什么该语言要求您仅在从
new[]
表达式获取的指针上调用delete[]
,并且这是唯一的释放该内存的方法。A dynamic array is more than just a sequence of elements. It contains information about the array size as well. Moreover, there is just one chunk of memory known to the allocator. So just like with any dynamic memory, you can only free what you allocated, not smaller subsets of it.
That's why the language requires that you only invoke
delete[]
on a pointer obtained from anew[]
expression, and that that is the only way to deallocate that memory.简单答案:因为语言规范规定您可以使用
delete[]
来执行此操作。更好的答案:因为毕竟对于堆管理器来说,
m_ppKeyValueList
指向的数组是单个大型分配,而不是m_iCapacity
连续的小分配,因此您只需告诉它分配的块从哪里开始,它将作为一个整体释放它(如果需要,在调用单个析构函数之后);如果它将每个元素作为单个单独的分配保留到分配的块列表中,这将是一种愚蠢的资源浪费(如果它为此使用位图,则可能没有足够的粒度来支持这种愚蠢的分配方案)。Simple answer: because the language specifications say that you do that with a
delete[]
.Better answer: because after all for the heap manager the array pointed by
m_ppKeyValueList
is a single large allocation, notm_iCapacity
consecutive small allocations, so you just have to tell it where the allocated block begins and it will deallocate it as a whole (after calling the single destructors if needed); if it kept each element as a single separated allocation into the allocated block lists it would be a stupid waste of resources (and if it used a bitmap for this it probably wouldn't have enough granularity to support this silly allocation scheme).因为
new int[5]
分配了一个足够大的连续块来容纳 5 个 int。new int
5 次分配 5 个小块,每个小块足以容纳一个 int。解除分配的数量必须等于分配的数量。Because
new int[5]
allocates one contiguous block big enough to hold 5 ints.new int
5 times allocates 5 small blocks, each big enough to hold a single int. The number of deallocations must equal the number of allocations.