简体   繁体   English

在MSVC上的数组初始化期间调用了没有复制或移动构造函数的析构函数

[英]Destructor called without copy or move constructor during array initialization on MSVC

I have tried this on MSVC versions 19.10.25019.0 and 19.11.25547.0 in debug and release builds and get the same result. 我已在调试和发行版本的MSVC版本19.10.25019.0和19.11.25547.0上尝试过此操作,并获得相同的结果。


The following program prints 0 1 2 3 4 5 . 以下程序打印0 1 2 3 4 5 I expected either 我期望

  • no output, or 没有输出,或者
  • a combination of move or copy constructor calls with the destructor calls. 移动或复制构造函数调用与析构函数调用的组合。

Instead, it seems the destructor was called for 6 of the 7 elements and no copy or move constructor calls were made. 相反,似乎在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'};
}

Why is the destructor being called 6 times without delete (or without the compiler initializing via a copy or a move)? 为什么析构函数被调用6次而没有删除(或者没有通过复制或移动初始化编译器)?

In playing around with this in the VC compiler, and inspecting the generated assembly code, this appears to be a compiler bug related to the MyChar() = default constructor. 在VC编译器中解决此问题并检查生成的汇编代码时,这似乎是与MyChar() = default构造函数有关的编译器错误。 Replacing it with MyChar() { } gets rid of the unexpected destructor calls. MyChar() { }替换它可以摆脱意外的析构函数调用。

By adding some additional code into the destructor, the objects being destroyed are the default-initialized members of arr1 . 通过在析构函数中添加一些其他代码,被销毁的对象是arr1的默认初始化成员。 Adding in a call to delete [] arr1 , along with including the address of the object being destroyed in the destructor, shows that the first element is destroyed once, while the other 6 are destroyed twice - once when arr1 is constructed, and again when the delete call is made. 加上对delete [] arr1的调用,并在析构函数中包含要破坏的对象的地址,表明第一个元素被破坏了一次,而其他6个被破坏了两次-一次在构造arr1时被破坏,一次在以下情况下被破坏:进行删除呼叫。

This should be reported to Microsoft. 这应该报告给Microsoft。 It occurs in both VC2015 and VC2017. 它同时在VC2015和VC2017中出现。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 在没有复制删除的情况下,是否可以确保在析构函数之前调用复制/移动构造函数? - In the absence of copy elision, is the copy/move constructor guaranteed to be called before the destructor? 使用动态数组复制构造函数和析构函数 - Copy Constructor and Destructor with a Dynamic Array 复制初始化:为什么即使关闭复制省略也没有调用移动或复制构造函数? - copy initialization : why move or copy constructor was not called even if copy-elision is turned off? 在构造函数之前调用析构函数? - Destructor called before move-constructor? 为什么在堆数组初始化中调用了两次复制构造函数? - Why copy constructor called twice in heap array initialization? 为什么在复制分配期间调用析构函数? - Why is the destructor being called during copy assignmment? C ++-构造函数,复制构造函数,Move构造函数,析构函数 - C++ - Constructor, Copy Constructor, Move Constructor, Destructor 复制构造函数是否不用于复制初始化或优化? - Copy constructor is not called for copy-initialization or optimized? 转换构造函数要求移动但不能复制 - Conversion constructor called for move but not for copy 为什么std :: vector :: emplace在没有调用任何拷贝构造函数的情况下调用析构函数? - Why does std::vector::emplace call destructor without any copy constructor called?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM