我有一段这样的代码:
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;
}
当我暂停程序以检查值(在断点处)时,第一个(vec[0]
)元素被销毁而第二个元素(vec[1]
)正常。这里发生了什么?这是编译器中的错误吗?我正在使用新的Visual Studio 2013。
答案 0 :(得分:5)
VS2013中的错误会导致对initializer_list的第一项进行双重删除。 这是流程:
delete[]
)销毁。最后一个元素首先被销毁。delete
)再次销毁。我在另一篇文章中看过这个,并使用调试器验证了行为。 见here
对于VS2013,initializer_list仅适用于基本类型。
答案 1 :(得分:0)
我想共享指针注意到共享指针对象将被销毁 拥有该对象的最后剩余的shared_ptr将被销毁。 拥有该对象的最后一个shared_ptr通过operator =或reset()分配另一个指针。 我希望这有帮助
答案 2 :(得分:0)
我没有VS2013,所以我在Windows中检查MinGW 4.7中的代码,我没有发现上面提到的问题。当我在该断点处停止时,第一个(vec [0])元素和第二个(vec [0])元素都不会被销毁。
所以我猜这个问题的原因是你在那个断点处写了一些简单的代码,vs的编译器优化它,所以你在两个元素的析构函数之间准确地停在一个奇怪的地方。
您可以发布上面的反汇编代码,我们可以明确地识别问题。 :)
答案 3 :(得分:0)
这可能是编译器中的一个错误。如果你向Data构造函数和析构函数添加一些日志记录,那么你会看到它正在发生。
std::cout << __FUNCTION << ":" << this << std::endl;
我在Visual Studio 2013中确认了该问题。在“clang”下,此代码的行为符合预期。