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