我在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次而没有删除(或者没有编译器通过复制或移动进行初始化)?
答案 0 :(得分:6)
在VC编译器中使用它并检查生成的汇编代码时,这似乎是与MyChar() = default
构造函数相关的编译器错误。用MyChar() { }
替换它可以消除意外的析构函数调用。
通过在析构函数中添加一些额外的代码,被销毁的对象是arr1
的默认初始化成员。添加对delete [] arr1
的调用,包括在析构函数中被销毁的对象的地址,显示第一个元素被销毁一次,而其他6个被销毁两次 - 一次arr1
是构建,并在删除调用时再次构建。
应该向Microsoft报告。它发生在VC2015和VC2017中。