gpt4 book ai didi

c++ - 当作为引用给出时, std::unique_ptr 是否会在作用域之后自动清理?

转载 作者:行者123 更新时间:2023-12-02 03:40:30 27 4
gpt4 key购买 nike

可以返回一个函数的指针,这在很多方面都很有用,但是是否建议从该返回值中获取引用?

#include <iostream>
#include <memory>

using namespace std;

unique_ptr<int> give_a_number(){
return std::make_unique<int>(6);
}

int main(){
int& ret = *give_a_number();
return ret;
}

根据 sanitizer ,没有发生泄漏:

user@comp: Scrapbook$ g++ main.cpp -fsanitize=address -g
user@comp: Scrapbook$

所以引用以某种方式被清理了,但我不明白为什么。清理是如何发生的,甚至 unque_ptr 如何能够跟踪数据。这应该被视为安全行为吗?这是社区中可接受的用法吗?

最佳答案

这里没有泄漏。一般来说,一个对象由std::unique_ptr拥有。只要 .release()永远被泄露不调用拥有 std::unique_ptr .

但是,您的程序确实存在未定义的行为,因为生命周期不正确。如果您存储对所拥有对象的引用或指针,您就承担了一些责任来确保正确的对象生命周期。

give_a_number()按值返回 std::unique_ptr拥有int目的。这个std::unique_ptr因此在语句中具体化为临时对象

int& ret = *give_a_number();

您不要将此临时项移动到任何持久项 std::unique_ptr实例。因此,当临时对象在语句末尾被销毁时,int它所拥有的也被摧毁了。现在你的引用是悬空的。

然后您可以使用 return ret; 中的悬空引用,导致未定义的行为。

您可以存储对所拥有对象的引用,但如果这样做,您必须确保 std::unique_ptr拥有引用的实例比 int 的生命周期更长引用以避免终身问题。例如。以下内容都可以:

int main(){
return *give_a_number(); // `std::unique_ptr` temporary outlives return value initialization
}
int main(){
auto ptr = give_a_number(); // `ptr` lives until `main` returns
int& ret = *ptr;
return ret;
}

通常,更安全的做法是像上面那样将智能指针存储在自动变量中,并通过使用 *ptr 取消引用来获取对象。 ,在需要的地方。 std::unique_ptr如果它没有被移动,那么它拥有的对象就会一直存活到 block 的末尾。

但它是完全正确的,例如通过*ptr到函数的引用。自 ptr超过这样的函数调用,不会有任何问题。

如果您通过*give_a_number(),这也有效。直接作为函数的参数,因为 std::unique_ptr临时的也将比这样的调用更长久。但在这种情况下 std::unique_ptr并且它所拥有的对象只会存活到语句结束(完整表达式),而不是 block 结束。

关于c++ - 当作为引用给出时, std::unique_ptr 是否会在作用域之后自动清理?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60433225/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com