c++ - 删除自定义数组导致堆错误

标签 c++ pointers

长话短说

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/

相关文章:

c++ - 如何修复由于 MySql Connector C++ 而无法解析的外部符号?

c++ - 从 jpg、dng 和 awr raw 文件获取元数据

c++ - 确定平台的行分隔符的可移植方法

c++ - 在 C++ 中为指针数组定义 NULL

c++ - C++中 '~'有什么用?

c++ - PostMessage 能否使工作线程中的变量更改在 GetMessage 之后在 UI 线程中可见?

c++ - 关于删除表达式,C++ 中缺少 "placement delete"

c - 基本 C 指针语法

c++ - 数组指针,(*ptr)[] 和 *ptr[] 有什么区别

c++ - 在 C++ 中,我无法掌握指针和类