“使用 unique_ptr 的 reset 方法:无效的指针释放()”

huangapple go评论65阅读模式
英文:

use method reset of unique_prt:free(): invalid pointer

问题

当我使用reset重新绑定unique_ptr时,发生了一些问题,但是使用std::make_unique时,一切正常。

int main() {
    unique_ptr<string> p = nullptr;
    auto l = [&p]() -> void {
        static string x {"1111"};
        cout << x << endl;
        //p = std::make_unique<string>(x);// 编译通过
        p.reset(&x);// 编译错误 free(): invalid pointer; 
        cout << p.get() << endl;
        return;
    };
    l();
    cout << p->length() << endl;
    cout << p.get() << endl;
    return 0;
}
英文:

When I use reset to rebind the unique_ptr, something bad happens but when use std::make_unique, everything is ok.

int main() {
    unique_ptr&lt;string&gt; p= nullptr;
    auto l=[&amp;p]()-&gt;void{
        static string x {&quot;1111&quot;};
        cout&lt;&lt;x&lt;&lt;endl;
        //p = std::make_unique&lt;string&gt;(x);// compile ok
        p.reset(&amp;x);//compile error free():invalid pointer; 
        cout&lt;&lt;p.get()&lt;&lt;endl;
        return;
    };
    l();
    cout&lt;&lt;p-&gt;length()&lt;&lt;endl;
    cout&lt;&lt;p.get()&lt;&lt;endl;
    return 0;
}

“使用 unique_ptr 的 reset 方法:无效的指针释放()”

I think that when the reset method is called, the string object is not really handed over to the unique_ptr management. When leaving the scope, the dtor is called twice

答案1

得分: 5

以下是您要翻译的内容:

"Both variants do compile without errors (provided one adds the missing parts). Your code invokes undefined behavior and likely crashes at runtime.

When you use std::make_unique like this:

p = std::make_unique&lt;string&gt;(x);

Then std::make_unique constructs a std::unique_ptr that manages the lifetime of a std::string that is constructed as a copy of x. You now have two strings, x and the one managed by p.

When you use reset like this:

p.reset(&amp;x);

You tell p to take ownership of x. However, x is not dynamically allocated. It makes no sense to transfer its ownership to a smart pointer. When ps destructor is called it will attempt to delete &amp;x but x was not allocated via new, hence there is undefined behavior. When the program terminates the lifetime of the static string ends and x is destroyed (again).

> I think that when the reset method is called, the string object is not really handed over to the unique_ptr management.

Yes it is. And that is the problem.

It is not clear what the actual purpose of the code is. To return string from the lambda:

#include &lt;string&gt;
#include &lt;iostream&gt;

int main() {
    auto l=[](){
        std::string x {&quot;1111&quot;};
        std::cout &lt;&lt; x &lt;&lt; std::endl;
        return x;
    };
    auto p = l();
    std::cout &lt;&lt; p.length() &lt;&lt; std::endl;
}"
英文:

Both variants do compile without errors (provided one adds the missing parts). Your code invokes undefined behavior and likely crashes at runtime.

When you use std::make_unique like this:

p = std::make_unique&lt;string&gt;(x);

Then std::make_unique constructs a std::unique_ptr that manages the lifetime of a std::string that is constructed as a copy of x. You now have two strings, x and the one managed by p.

When you use reset like this:

p.reset(&amp;x);

You tell p to take ownership of x. However, x is not dynamically allocated. It makes no sense to transfer its ownership to a smart pointer. When ps destructor is called it will attempt to delete &amp;x but x was not allocated via new, hence there is undefined behavior. When the program terminates the lifetime of the static string ends and x is destroyed (again).


> I think that when the reset method is called, the string object is not really handed over to the unique_ptr management.

Yes it is. And that is the problem.


It is not clear what the actual purpose of the code is. To return string from the lambda:

#include &lt;string&gt;
#include &lt;iostream&gt;

int main() {
    auto l=[](){
        std::string x {&quot;1111&quot;};
        std::cout &lt;&lt; x &lt;&lt; std::endl;        
        return x;
    };
    auto p = l();
    std::cout &lt;&lt; p.length() &lt;&lt; std::endl;
}

huangapple
  • 本文由 发表于 2023年5月10日 22:27:57
  • 转载请务必保留本文链接:https://go.coder-hub.com/76219641.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定