长话短说
Boost-Test-Framework 在通过所有测试并泄漏所有内存时崩溃且未给出任何错误。
使用上述析构函数实现的测试多次失败。清除函数也会抛出堆错误。
我们对 dtor 做错了什么?
长话短说
这是关于大学家庭作业,以及我 friend 对上述问题的解决方案。为了更熟悉 C 风格的指针和更底层的编程风格,我们需要实现自己的动态数组。
根据我们老师的 900-LOC 提升测试框架,他的作业已完成且功能齐全。唯一的问题是当测试退出或调用已实现的 dtor 时崩溃(或堆错误,因为没有弹出真正的错误消息)。
他的动态数组使用三个指针:pFirst、pLast 和 pEnd
,指向数组的第一个元素,指向数组中最后一个元素之后的那个,以及指向最后一个非-还分别在数组中分配了元素。
只要他不尝试删除任何指针,他的程序就会通过。这是个坏主意,但是,嘿,这让他通过了任务。现在。
我的 friend 曾多次尝试实现析构函数,但它们都导致堆错误并导致测试框架失败。
// 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 做错了什么,清晰且一般?
最佳答案
断言失败:_BLOCK_TYPE_IS_VALID(pHead->nBlockUse)
表示堆损坏。通常,当您写入已分配内存的末尾时,就会发生这种情况。
我在您的代码中看到以下问题:在 Field::clear
中,您将指向已分配内存的指针存储在 pFirst
中,并立即用 pLast
覆盖它.我认为您应该将其更改为 pLast = pFirst;
。
老师推荐的dtor对我来说毫无意义。如果您使用 new[]
进行分配,然后使用 delete[]
进行释放,请不要分别调用每个析构函数并使用 delete
。
关于c++ - 删除自定义数组导致堆错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4063733/