我正在做练习问题,问题是要创建一个析构函数以确保没有任何内存泄漏。当我使用这个析构函数时,我在执行系统(“暂停”)后收到此错误;:
这是复制构造函数:
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个析构函数语句时,错误不再显示。
感谢。
答案 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)
在赋值运算符中,您将项目从一个数组复制到另一个数组。但是如果本地数组的大小小于传递给运算符的参数呢?你将超过数组的大小。