TL; DR
Сбой Boost-Test-Framework без ошибок при прохождении всех тестов и утечке всей памяти.
Тест не пройден несколько раз с упомянутыми реализациями деструктора. Функция очистки также выдает ошибку кучи.
Что мы делаем не так с дтором?
TL; DR
Это относится к домашнему заданию в колледже и решению моего друга к указанной проблеме. Чтобы лучше познакомиться с указателями в стиле C и более низкоуровневым стилем программирования, нам нужно было реализовать собственный динамический массив.
Его задание является полным и полностью функциональным в соответствии с инструкцией 900-LOC Boost-Test нашего учителя. Единственная проблема - сбой (или ошибка кучи, так как не появляется сообщение об ошибке), когда тест завершается или вызывается внедренный dtor.
В его динамическом массиве используются три указателя: pFirst, pLast and pEnd
, указывающий на первый элемент массива, на один после последнего элемента в массиве и указывающий на последний еще не выделенный элемент в массиве соответственно.
Его программа прошла, пока он не пытался удалить указатели. Это плохая идея, но эй, она позволила ему выполнить задание. На данный момент.
Мой друг несколько раз пытался реализовать деструктор, но они оба вызывают ошибки кучи и приводят к сбою тестовой среды.
// Teacher's recommended dtor.
Field::~Field()
{
for(int i(0); i != this->size(); ++i)
(pFirst+i)->~T();
delete pFirst;
pFirst = pLast = pEnd = NULL;
}
и
// My recommendation to friend.
Field::~Field()
{
delete[] pFirst;
pFirst = pLast = pEnd = NULL;
}
оба сбоя с одной и той же ошибкой кучи.
Assertion failed: _BLOCK_TYPE_IS_VALID(pHead->nBlockUse)
Типичная цепочка тестов выглядит так:
BOOST_AUTO_TEST_CASE( TEST_clear )
{
Field f( 3, 4.0f );
f.clear(); // Error here IF we use delete in the clear method.
BOOST_CHECK( f.size()==0 );
BOOST_CHECK( f.capacity()==4 );
} // Error here; during destruction IF we have implemented the dtor.
Метод clear выдает ту же ошибку, когда мы пытаемся заменить массив, поэтому у нас просто есть:
void Field::clear()
{
size_t capa = capacity();
T *temp =pFirst;
pFirst = new T[capa];
pLast = pFirst;
pEnd = pFirst+capa;
}
Что мы делаем не так с dtor, понятно и вообще когда имеем дело с удалением указателей?