Здравствуйте Vi2, Вы писали:
Vi2>Здравствуйте Al-Ko, Вы писали:
AK>>когда их копируют из m_pData в pNewData, они копируются в pNewData, а в m_pData остаются, или нет? Их уже два экземпляра, не так ли?Если остаются, то delete[] m_pData должно работать корректно.
AK>>Спасибо, я учту замечания и проверю с TYPE c деструкторами — с простыми типами это работает хоть с пятимерными массивами, только Redimension можно делать только последнему измерению (как в SafeArray или бейсиковских массивах)
Vi2>Введу псевдо-обозначения О(ptr) — объект О типа TYPE имеет указатель на динамически выделяемую память ptr (есть аналогия с классом AKVector), чтобы было видно влияние деструктора.
Vi2>m_pData->> O0(ptr0),O1(ptr1),...,ON(ptrN), где N=m_nSize
Vi2> TYPE* pNewData = new TYPE[nNewSize];
pNewData->> O'0(NULL),O'1(NULL),...,O'N(NULL),O'N+1(NULL), где N=m_nSize
Vi2> memmove(pNewData, m_pData, m_nSize * sizeof(TYPE));
pNewData->> O0(ptr0),O1(ptr1),...,ON(ptrN),O'N+1(NULL), где N=m_nSize
Vi2> delete [] m_pData;
Vi2>~O0 освободил ptr0,~O1 освободил ptr1,...,~ON освободил ptrN, где N=m_nSize
m_pData->> O0(ptr0),O1(ptr1),...,ON(ptrN), где N=m_nSize
Vi2> m_pData = pNewData;
m_pData->> O0(ptr0),O1(ptr1),...,ON(ptrN),O'N+1(NULL), где N=m_nSize
Vi2>
Vi2>Если теперь попытаться освободить delete [] m_pData; — в деструкторе или методе Add — произойдёт следующее
Vi2>~O0 будет освобождать ptr0 и вылетит по ексепшену (прерыванию).
Vi2>Конечно, лучше бы представить это всё графически, но нет у меня такой возможности.
да, вот так оно веселее будет:
void AKVector<TYPE>::Remove(long nIndex, long nCount /* = 1 */)
{
ATLASSERT(nIndex >= 0);
ATLASSERT(nCount >= 0);
ATLASSERT(nIndex + nCount <= m_nSize);
long nNewSize = m_nSize - nCount;
TYPE* pNewData;
if(nNewSize > 0)
pNewData = (TYPE*) new BYTE[nNewSize * sizeof(TYPE)];
else
pNewData = NULL;
if(nIndex > 0)
memcpy(pNewData, m_pData, nIndex * sizeof(TYPE));
if(nIndex < nNewSize)
memcpy(&pNewData[nIndex], &m_pData[nIndex + nCount], (nNewSize-nIndex)* sizeof(TYPE));
DestructElements<TYPE>(&m_pData[nIndex], nCount);
delete[] (BYTE*)m_pData;
m_nSize = nNewSize;
m_pData = pNewData;
}
inline void STDAPICALLTYPE DestructElements(TYPE* pElements, int nCount)
{
ATLASSERT(nCount == 0 ||
AtlIsValidAddress(pElements, nCount * sizeof(TYPE)));
// call the destructor(s)
for (; nCount--; pElements++)
pElements->~TYPE();
}
(аналогичные изменения для Add и Insert)
проверял — работает, еще раз благодарю за замечание