类析构函数错误

Class Destructor Error

本文关键字:错误 析构函数      更新时间:2023-10-16

我正在做一个练习题,问题要求创建一个析构函数以确保没有任何内存泄漏。当我使用此析构函数时,在执行系统("暂停")后出现此错误;

https://i.stack.imgur.com/mWu0A.jpg

下面是复制构造函数:

    vector_of_int::vector_of_int ( const vector_of_int& a_vector )
    {
        an_array = new int[ a_vector.size ];
        this->size = a_vector.size;
        for( int i = 0; i < size; ++i )
        {
            an_array[i] = a_vector.an_array[i];
        }
    }

和赋值运算符:

    vector_of_int& vector_of_int::operator= ( const vector_of_int& a_vector )
    {
        if( this == &a_vector )
        {
            return *this;
        }
        this->size = a_vector.size;
        for( int i = 0; i < size; ++i )
        {
            an_array[i] = NULL;
            an_array[i] = a_vector.an_array[i];
        }
            return *this;
     }

我在网上搜索了一下,有人提到这可能是由于复制构造函数指向相同的内存位置。为了测试这一点,在我的main()函数中,我将数据推送到每个向量a,b,c中,并重新打印它们,它们都是不同的。此错误在调用析构函数并进入下一行系统("暂停")后显示;按下任何键后,它会显示。这是main()的结尾:

    a_vector.~vector_of_int();
    b_vector.~vector_of_int();
    c_vector.~vector_of_int();
    cout << "n";
    system("pause");
    return 0;

主.exe 是否在主大括号结束后再次调用析构函数?当我注释所有 3 个析构函数语句时,错误不再显示。

谢谢。

不要显式调用析构函数,当对象超出范围时,这将自动发生(从代码中,我相信向量是堆栈分配的,给定用于调用析构函数的.表示法)。即使它们是在堆上分配的,使用 new ,您仍然不会显式调用析构函数,而是使用 delete

此外,在赋值运算符中,this->size会更新,但an_array不会更新。如果a_vector.size > this->size,那么它将导致an_array越界访问,因为它没有足够的元素:delete[]new[] an_array

从代码中可以看出您正在显式调用析构函数。虽然这是合法的并且有一些用途,但通常情况下,您不应该显式调用析构函数,因为当对象超出范围时(或者delete为指针调用),它们将自动调用。在已销毁的对象上执行析构函数是未定义的行为。

在您的特定代码中,析构函数可能正在释放内存,第二次(在局部变量范围结束时自动调用)它尝试释放手动调用已释放的内存并触发运行时错误。

我想你已经像这样创建了你的向量:

vector_of_int v;

不要删除它 - 它是自动存储。它将在范围结束时自动删除

如果您已将矢量创建为:

vector_of_int *v = new vector_of_int();

调用delete操作员将其删除:

delete v;

在 assigment 运算符中,您将项目从一个数组复制到另一个数组。但是,如果本地数组的大小小于传递给运算符的参数怎么办?您将超过阵列的大小。