1
std::unique_ptr<std::string> foo_ptr(new std::string("foo"));
foo_ptr.reset(foo_ptr.get());
std::cout << *foo_ptr << std::endl; //prints "foo" so obj hasn't been deleted
//runtime error: "pointer being freed was not allocated"

実行時エラーが発生するのはなぜですか?「foo」が出力されるのは単なる偶然ですか?

4

2 に答える 2

7

n3376 20.7.1.2.5/4 および 5 からの引用。

効果: 格納されたポインターに p を割り当て、格納されたポインター old_p の古い値が nullptr と等しくない場合は、get_deleter()(old_p) を呼び出します。

[ 注: get_deleter() の呼び出しは *this を破棄する可能性があるため、これらの操作の順序は重要です。— エンドノート]

そのため、このポインターを逆参照すると、未定義の動作が発生します。

事後条件: get() == p. [ 注: get_deleter() の呼び出しが *this を破棄する場合、事後条件は成立しません。これは、this->get() が有効な式ではなくなったためです。— エンドノート]

于 2013-06-06T11:40:49.217 に答える
3
foo_ptr.reset(foo_ptr.get());

この行は、foo_ptr の現在のポインターを「解放」し、foo_ptr.get() の値に設定します。値が更新される前に foo_ptr.get() がフェッチされるため、古い場所を指します。

これをしないでください。未定義の動作につながります。resetすでに持っているのと同じ値で呼び出すべきではありません。

于 2013-06-06T11:40:08.283 に答える