TL; DR
Boost-Test-Framework在传递所有测试并泄漏所有内存时没有发生错误而崩溃。
使用提到的析构函数实现多次测试失败。清除函数也会引发堆错误。
我们在dtor上做错了什么?
TL; DR
这与大学家庭作业有关,也是我朋友解决问题的方法。为了更多地使用C风格的指针和更低级的编程风格,我们需要实现自己的动态数组。
根据我们老师的900-LOC Boost-Test Framework,他的任务完整且功能齐全。唯一的问题是当测试退出或调用已实现的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做了什么错误,明确和一般?
答案 0 :(得分:3)
Assertion failed: _BLOCK_TYPE_IS_VALID(pHead->nBlockUse)
表示堆损坏。通常在写入已分配内存的末尾时发生。
我在您的代码中看到以下问题:在Field::clear
中,您将指针存储在pFirst
中的已分配内存中,并立即用pLast
覆盖它。我认为您应该将其更改为pLast = pFirst;
。
老师推荐的dtor对我没用。如果您使用new[]
进行分配,然后使用delete[]
取消分配,请不要单独调用每个析构函数并使用delete
。
答案 1 :(得分:2)
如果pFirst
指向数组的第一个元素,那么您的“老师建议的dtor”就错了。你需要说delete[] pFirst
来解除分配数组。
但是有许多问题可能导致这种情况,例如由其他一些函数引起的堆损坏。尝试在内存损坏检查程序(如Valgrind)中运行它,以查看是否溢出了堆缓冲区。