我不太习惯使用weak_ptr
,我正面临一个非常混乱的情况。我正在将Intel XE 2019 Composer update 5(package 2019.5.281)与Visual Studio 2019 ver。 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
被修改/无效是正常的吗?我对获得的结果感到有些困惑。说实话我没想到会有这个结果...
虽然错误发生在64位配置中,但没有出现在32位中。在此更高版本的配置中,结果是预期的。
该错误仅在Debug中发生。当我构建Release时,得到了预期的结果。
它看起来像是调试库中的一个错误,带有哨兵值。使用我提到的那行很容易检查:
int i = 1; cout << i << " " << ++i << endl;
如果输出是2 2
而不是1 2
,则说明编译器不兼容,可能仍将这种情况视为UB。在这种情况下,通过调用reset()
可能会错误地使用前哨值。删除通过将新对象放置在预分配的静态缓冲区中而创建的对象被删除时,也会发生类似的事情,在调试模式下,它会被带有哨兵值的某些实现所覆盖。
看来这是英特尔ICC方面的真正错误;我已经举报了。
再次感谢您帮助我指出这个问题。