类析构函数错误

时间:2012-07-03 19:53:49

标签: c++ class destructor copy-constructor

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

http://imgur.com/r2bvF

这是复制构造函数:

    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;

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

感谢。

4 个答案:

答案 0 :(得分:9)

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

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

答案 1 :(得分:2)

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

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

答案 2 :(得分:1)

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

vector_of_int v;

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

如果您将矢量创建为:

vector_of_int *v = new vector_of_int();

致电delete运营商将其删除:

delete v;

答案 3 :(得分:1)

在赋值运算符中,您将项目从一个数组复制到另一个数组。但是如果本地数组的大小小于传递给运算符的参数呢?你将超过数组的大小。