重新分配变量,删除调用了两次(C++)
Reassigning variable, delete called twice (C++)
我的编程背景是Java世界,但我刚刚开始学习C++。作为一名Java程序员,我偶然发现了一个相当琐碎、可能很无聊的问题:
我有一个带有数组的类,它在构造函数中通过new初始化,在析构函数中删除。现在,当我创建这个类的对象并将这个类的另一个对象分配给同一个变量时(至少我认为是这样(,当变量离开作用域时,析构函数中的delete[]方法似乎被调用了两次(在本例中是main((函数((调试器会给我一个_BLOCK_TYPE_is_VALID断言失败的警告(。
为什么?为什么在我给f分配一个新对象之前没有调用解构器?我怎样才能明确地删除Foo(1(?这里到底发生了什么?
class Foo{
private:
int *field;
public:
Foo(int size){
field = new int[size];
}
~Foo(){
delete[] field;
}
};
int main(){
Foo f = Foo(1);
f = Foo(2);
}
在C++世界中有一种叫做三规则的东西。
类将自动为您生成析构函数、复制构造函数和赋值运算符。
如果必须手动定义其中一个函数,则可能必须定义这三个函数。
在您的情况下,应该定义两个复制函数,以便Foo
的副本获得自己的field
副本。添加这两个功能:
class Foo{
Foo( const Foo &f ) {
size = f.size;
field = new int[size];
std::copy( f.field, f.field + size, field );
}
Foo& operator=( const Foo &f ) {
// Leverage the logic that was already written in the copy constructor
Foo tmp(f);
std::swap( *this, temp );
return *this;
}
};
请注意,我假设您已将size
存储在Foo
对象中。您可能需要在实际应用程序中存储这些信息
您没有遵守三条规则,这很糟糕。因为默认的复制构造函数执行浅层复制,所以所有的自动变量(f
和临时变量(都有指向同一个int
的field
成员,在调用析构函数时会多次销毁该成员。
实现一个正确的复制构造函数,或者使用C++习惯用法并避免手动管理——即使用std::vector
。
相关文章:
- g++的分段错误(在NaN上使用to_string两次时)
- 蛇在C++不会连续转两次
- 检查一个数组是否包含在另一个数组中,以相反的顺序,至少两次
- 从具有按值捕获的 lambda 移动构造 std::函数时,移动构造函数调用两次
- 我应该如何去缓解两次出现的cin?
- Realloc 两次无法在 Visual Studio 上运行
- 使用 getline(cin, var) 两次在进行字符串比较时会产生错误 (==)
- 为什么映射插入和 map.find() 的单次迭代比插入和 map.find() 的两次单独迭代慢得多
- C++析构函数调用两次,堆栈分配的复合对象
- 为什么参数在构造 std::thread 时移动两次
- Qt插槽调用了两次
- 做 std::用相同的unique_ptr移动两次
- C++两次定义相同的函数会导致错误
- 为什么具有静态存储持续时间的同一内联变量在包含在 VS2017 编译的两个翻译单元中时会构造和销毁两次
- 对于优化级别为 0 的 std::vector,析构函数被调用两次
- 使用柯南打包时如何避免列出两次依赖?
- 为什么要执行两次位移((x >> 4)<< 4)?
- 对结构向量进行两次排序
- 如果我使用同一个密钥推送用户数据两次,会发生什么
- 谷歌测试发现在macOSX上添加并运行了我的所有测试两次