在MSVC

时间:2017-11-20 15:28:42

标签: c++ visual-studio visual-c++

我在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次而没有删除(或者没有编译器通过复制或移动进行初始化)?

1 个答案:

答案 0 :(得分:6)

在VC编译器中使用它并检查生成的汇编代码时,这似乎是与MyChar() = default构造函数相关的编译器错误。用MyChar() { }替换它可以消除意外的析构函数调用。

通过在析构函数中添加一些额外的代码,被销毁的对象是arr1的默认初始化成员。添加对delete [] arr1的调用,包括在析构函数中被销毁的对象的地址,显示第一个元素被销毁一次,而其他6个被销毁两次 - 一次arr1是构建,并在删除调用时再次构建。

应该向Microsoft报告。它发生在VC2015和VC2017中。