开发者

Why does calling 'delete' in a specific way on a dynamic array not work?

开发者 https://www.devze.com 2023-04-08 16:30 出处:网络
I\'m wondering why th开发者_开发知识库is code doesn\'t work: void KeyValueList::Release() { //(m_ppKeyValueList is a dynamic array of pointers to objects on the heap)

I'm wondering why th开发者_开发知识库is 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?


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.


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).


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.


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[].

0

精彩评论

暂无评论...
验证码 换一张
取 消