c++ - Delete[] 导致 C++ 崩溃

标签 c++ destructor dynamic-arrays

<分区>

我正在使用此 code from my previous SO post 中的相同代码但我做了一些改变。我的问题是我有一个动态数组,我在复制构造函数的运算符重载内部调用了 delete[],但出现以下错误。

在 Lab3.exe 中的 0x0F7063BB (ucrtbased.dll) 处抛出异常:0xC0000005:访问冲突读取位置 0xCCCCCCBC。

如果有这个异常的处理程序,程序可以安全地继续。

谁能帮我理解为什么? 我检查了相关问题,但存在与我所看到的不同的错误,而且我没有在我的谷歌搜索中找到结果。我在 visual studio 2015 上使用 C++ 11。

#include "ListArray.h"

template < typename DataType >
List<DataType>::List ( int maxNumber )
{
    //maxSize = MAX_LIST_SIZE; maybe???
    maxSize = maxNumber;
    dataItems = new DataType[maxSize];
    size = maxSize - 1;
    cursor = 0; // sets cursor to the first value in list
    for (; cursor <= size; cursor++)
        dataItems[cursor] = 1;
    cursor = 0;
}

template < typename DataType >
List<DataType>::List ( const List& source )
{
    *this = source; // should be handled by copy constructor
}

template < typename DataType >
List<DataType>& List<DataType>::operator= ( const List& source )
{
    if (this != &source)
    {
        maxSize = source.maxSize;
        size = source.size;
        cursor = source.cursor;
        delete []dataItems; // clears dataItems, weird run-time error here. Why? 
        dataItems = new DataType[size];
        for (int count = 0; count < size; count++)
            dataItems[count] = source.dataItems[count];
    }
    else
        // do nothing, they are the same so no copy is made
        return *this;
}

template < typename DataType >
List<DataType>::~List ()
{
    maxSize = 0;
    size = 0;
    cursor = -1;
    delete[] dataItems;
}

编辑: 我最初发布了其他几个不完整的函数,它们也是我正在尝试构建的程序的一部分。我的意思是只包括那些我知道会产生我的问题的。我为糟糕的帖子道歉。

最佳答案

如果你打算使用赋值运算符来制作你的拷贝,你需要一个空对象作为开始,否则 operator= 在尝试清理之前的旧内容时会可怕地失败替换它们(正如 Sam 在他的回答中解释的和 MikeCAT 在他的评论中提到的——给他们投票——以及什么 Dieter told you on your earlier question)。

从 C++11 开始,构造函数链也称为构造函数委托(delegate)是可能的,如下所示:

template < typename DataType >
List<DataType>::List ( const List& source )
    : List() /* default construct object before proceeding */
{
    *this = source; // should be handled by copy constructor
}

另一种选择是让复制构造函数自己负责创建默认对象,这正是 C++98 和 C++03 中所需要的:

template < typename DataType >
List<DataType>::List ( const List& source )
    : maxSize(0), dataItems(NULL), size(0) // initialize members
{
    *this = source; // should be handled by copy constructor
}

但这是在复制默认构造函数的功能,因此只要您的编译器支持 C++11 功能,就更愿意调用现有构造函数。

构造函数委托(delegate)的细节……变得复杂了。除其他事项外,通常从对象构造函数内部抛出的任何异常都会阻止对象永远存在,并且不会调用析构函数。当使用委托(delegate)时,对象在任何构造函数完成时变为事件状态,包装构造函数内的异常将面对一个已经事件的对象并为您调用析构函数。这种行为可能是合意的,也可能不是合意的,但这是需要注意的事情,因为异常安全在现代 C++ 中很重要。

关于c++ - Delete[] 导致 C++ 崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37848717/

相关文章:

c++ - QBoxLayout间距

C++ 存储、加载和查找词典的最有效方法

c++ - 删除 std::unique_ptr<Base> 容器中的派生类

c++ - 使用 decltype 和\或 std::remove_reference 调用析构函数

c - 动态分配的二维数组出错

c++ - 有没有一本使用 C++ 编写控制台/终端应用程序的书?

c++ - 为什么这种移动和值构造函数的组合对于 MSVC 不明确,但对于 C++17 及更高版本中的 Clang 和 GCC 却不明确

c++ - 单例实例释放

loops - 这是 transient 的正确用法吗?

c - malloc、realloc 后出现 "Pointer being freed was not allocated."错误