我已经在 MSVC 版本 19.10.25019.0 和 19.11.25547.0 的调试和发布版本中尝试过此操作,并获得了相同的结果。
以下程序打印 0 1 2 3 4 5
。
我希望要么
- 没有输出,或者
- 移动或复制构造函数调用与析构函数调用的组合。
相反,似乎为 7 个元素中的 6 个调用了析构函数,并且没有进行复制或移动构造函数调用。
#include <iostream>
struct MyChar {
MyChar(char c) : c{c}{}
MyChar() = default;
MyChar(const MyChar&) { std::cout << "copy"; };
MyChar& operator=(const MyChar&) { std::cout << "assign"; return *this; };
MyChar(MyChar&&) { std::cout << "move"; };
MyChar& operator=(const MyChar&&) { std::cout << "move assign"; return *this; };
~MyChar() { std::cout << cnt++ << '\t'; }
char c{'H'};
static int cnt;
};
int MyChar::cnt{};
int main()
{
auto arr1 = new MyChar[7]{'D'};
}
为什么析构函数在没有删除的情况下被调用 6 次(或者编译器没有通过复制或移动进行初始化)?
最佳答案
在 VC 编译器中尝试这个,并检查生成的汇编代码,这似乎是一个与 MyChar() = default
构造函数相关的编译器错误。将其替换为 MyChar() { }
可以消除意外的析构函数调用。
通过在析构函数中添加一些额外的代码,被销毁的对象是 arr1
的默认初始化成员。添加对 delete [] arr1
的调用,以及在析构函数中包含被销毁对象的地址,表明第一个元素被销毁一次,而其他 6 个被销毁两次 - 一次当arr1
被构造,并在进行 delete 调用时再次构造。
这应该报告给 Microsoft。它出现在VC2015和VC2017中。
关于c++ - 在 MSVC 上的数组初始化期间调用的析构函数没有复制或移动构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47395489/