weak_ptr重置会影响shared_ptr吗?

时间:2019-10-04 13:20:34

标签: c++ c++17 smart-pointers visual-studio-2019 icc

我不太习惯使用weak_ptr,而且面临一种非常令人困惑的情况。我正在将 Intel XE 2019 Composer更新5 软件包2019.5.281 )与 Visual Studio 2019版本结合使用。 16.2.5 。我用64位编译。我使用标准的 C ++ 17

这是我的加标解决方案的代码:

#include <memory>
#include <iostream>

using namespace std;

int main( int argc, char* argv[] )
{
    shared_ptr<int> sp = make_shared<int>( 42 );
    cout << "*sp = " << *sp << endl;

    weak_ptr<int> wp = sp;
    cout << "*sp = " << *sp << ", *wp = " << *wp.lock() << endl;

    wp.reset();
    cout << "*sp = " << *sp << endl;

    return 0;
}

我期望的输出是:

*sp = 42
*sp = 42, *wp = 42
*sp = 42

...但是这是我获得的:

*sp = 42
*sp = 42, *wp = 42
*sp = -572662307

怎么回事?重置关联的shared_ptr时,weak_ptr被修改/无效是正常的吗?我对获得的结果感到有些困惑。说实话我没想到会有这个结果...

编辑1

该错误发生在 64位配置中,但不是 32位。在此更高版本的配置中,结果是预期的。

编辑2

该错误仅在 Debug 中发生。当我构建发布时,我得到了预期的结果。

2 个答案:

答案 0 :(得分:2)

看来这是英特尔ICC方面的真正错误;我已经报告了。

再次感谢您帮助我指出了这个问题。

答案 1 :(得分:1)

它看起来像是调试库中的一个带有前哨值的错误。使用我提到的那行很容易检查:

int i = 1; cout << i << " " << ++i << endl;

如果输出是2 2而不是1 2,则说明编译器不兼容,可能仍将这种情况视为UB。在这种情况下,调用reset()可能会错误地使用前哨值。删除通过在预分配的静态缓冲区中放置new所创建的对象会发生类似的情况,在调试模式下,它会被带有哨兵值的某些实现所覆盖。