2

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?

0

4 Answers 4

4

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.

Sign up to request clarification or add additional context in comments.

Comments

3

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

1 Comment

I'm claiming that the C++ language doesn't work in your way (the standard specifies that whatever you allocated with new T[...] is deallocated with delete[], and your code could lead to strange behavior into the C++ heap allocator) and that supporting that allocation scheme would be pointless and very inefficient.
0

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.

Comments

0

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.