2010-10-31 82 views
1

TL; DR删除自定义阵列导致堆错误

升压试验框架崩溃,并没有同时通过所有测试和泄漏的所有内存给定的错误。

测试失败多次提到的析构函数实现。清除函数也会抛出堆错误。

我们在做什么错误的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

@Pointy:他现在修正了一个错误:P – IAE 2010-10-31 15:53:39

回答

3

Assertion failed: _BLOCK_TYPE_IS_VALID(pHead->nBlockUse)表示堆损坏。通常它会在您分配内存的末尾写入时发生。 我在代码中看到以下问题:在Field::clear中,您将指针指向分配的内存,存储在pFirst中,并立即由pLast覆盖它。我认为你应该改为pLast = pFirst;

老师推荐的dtor对我没有意义。如果您使用new[]进行分配,然后使用delete[]进行取消分配,请勿分别调用每个析构函数并使用delete

+0

为了澄清,你还想对每个对象调用delete,对吧?我同意手动调用每个对象上的析构函数的奇怪之处。 – MintyAnt 2013-02-09 07:24:22

+0

@MintyAnt:不可以。由于'new T []'用于分配数组,所以应该使用delete []来释放整个数组。在每个对象上调用delete都是一个错误。 – vitaut 2013-02-09 14:30:45

2

如果pFirst指向数组的第一个元素,那么你的“老师推荐的dtor”是错误的。你需要说delete[] pFirst来释放数组。

但是有很多问题可能导致这种情况,比如由其他函数引起的堆损坏。尝试在内存损坏检查程序(如Valgrind)中运行此操作,以查看是否溢出了堆缓冲区。

相关问题