19

I have a piece of code like this:

class Data
{
    public:
        Data(const std::vector<int> &_data)
        {
            my_data = _data;
        }

    private:
        std::vector<int> my_data;
};


int main()
{
    std::vector<std::shared_ptr<Data>> vec = {
        std::shared_ptr<Data>(new Data(std::vector<int>({ 1, 2 ,3 }))),
        std::shared_ptr<Data>(new Data(std::vector<int>({ 3, 4 ,5 })))
    };

    // breakpoint

    return 0;
}

somehow when I pause the program to check values (at breakpoint), the first (vec[0]) element is destroyed while the second one (vec[1]) is fine. What is going on here? Is that a bug in compiler? I am using new Visual Studio 2013.

4

4 回答 4

5

发生的情况是 VS2013 中的一个错误导致对 initializer_list 的第一项进行双重删除。这是流程:

  1. initializer_list 被构造。
  2. 目标向量保留大小为 1 并复制第一项(通过复制构造函数)。
  3. 向量缓慢增长到 initializer_list 大小。
  4. initializer_list 通过向量析构函数(即delete[])销毁。最后一个元素首先被销毁。
  5. 第一个元素通过标量析构函数(即delete)再次销毁。

我在另一篇文章中看到了这一点,并使用调试器验证了该行为。看这里

对于 VS2013,initializer_list 仅适用于基本类型。

于 2013-11-28T12:08:42.160 回答
0

这可能是编译器中的一个错误。如果您向 Data 构造函数和析构函数添加一些日志记录,那么您将看到正在发生的事情。

std::cout << __FUNCTION << ":" << this << std::endl;

我在 Visual Studio 2013 中确认了该问题。在“clang”下,此代码的行为符合预期。

于 2013-11-22T06:04:27.613 回答
0

I didn't have VS2013, so I check the code in MinGW 4.7 in windows, I didn't found the problem above-mentioned. When I stop at that breakpoint, both the first (vec[0]) element and the second (vec[0]) element all is not destroyed.

So I guess that this problem's reason is that you write some simple code at that breakpoint, vs's complier optimize it, so you stopped at a strange place exactly between two elements' destructor function.

You can post out the disassembly code above that we can identify the problem explicitly. :)

于 2013-11-17T04:22:47.473 回答
0

我想这与共享指针有关,如果最后一个拥有该对象的 shared_ptr 被销毁,则共享指针对象将被销毁。最后剩下的拥有该对象的 shared_ptr 通过 operator= 或 reset() 分配另一个指针。我希望这有帮助

于 2013-11-12T06:13:31.670 回答