为什么调用“删除”会发生错误?以特定方式在动态数组上不起作用?

发布于 2024-12-06 17:26:24 字数 537 浏览 0 评论 0原文

我想知道为什么这段代码不起作用:

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

葬心 2024-12-13 17:26:25

情况 1m_ppKeyValueList 是“指向堆上对象的指针的动态数组
在这种情况下,您确实需要一块一块地删除m_ppKeyValueList。如果这就是您的意思,您的声明将采用以下形式 SomeType ** m_ppKeyValueList; 您的分配和释放应该类似于

Allocation:

m_ppKeyValueList = new SomeType*[m_iCapacity];
for (int i = 0; i < m_iCapacity; ++i) {
  m_ppKeyValueList[ii] = new SomeType;
}

Deallocation:

for (int i = 0; i < m_iCapacity; ++i) {
  delete m_ppKeyValueList[ii];
}
delete[] m_ppKeyValueList;

但是,您的代码失败表明您没有“指向堆上对象的动态指针数组。”

情况 2m_ppKeyValueList 是堆上的动态对象数组
在这里,您的声明将采用 SomeType * m_ppKeyValueList; 的形式,而不是逐段分配,您的分配和释放采用更简单的形式:

分配:

m_ppKeyValueList = new SomeType[m_iCapacity];

释放:

delete[] 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 like

Allocation:

m_ppKeyValueList = new SomeType*[m_iCapacity];
for (int i = 0; i < m_iCapacity; ++i) {
  m_ppKeyValueList[ii] = new SomeType;
}

Deallocation:

for (int i = 0; i < m_iCapacity; ++i) {
  delete m_ppKeyValueList[ii];
}
delete[] m_ppKeyValueList;

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 heap
Here 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:

m_ppKeyValueList = new SomeType[m_iCapacity];

Deallocation:

delete[] m_ppKeyValueList;

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 with delete. If you allocate it with new[] you need to destroy it with delete[].

云淡风轻 2024-12-13 17:26:24

动态数组不仅仅是元素序列。它还包含有关数组大小的信息。此外,分配器只知道一个内存块。因此,就像任何动态内存一样,您只能释放分配的内容,而不能释放其较小的子集。

这就是为什么该语言要求您仅在从 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 a new[] expression, and that that is the only way to deallocate that memory.

陌伤ぢ 2024-12-13 17:26:24

简单答案:因为语言规范规定您可以使用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, not m_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).

涙—继续流 2024-12-13 17:26:24

因为 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文