【问题标题】:Can references cause memory leaks? [duplicate]引用会导致内存泄漏吗? [复制]
【发布时间】:2015-11-05 21:25:26
【问题描述】:

考虑以下 C++ 代码。

struct foo { std::string value; }

inline foo bar() { return { "42" }; }

现在想象一下,我有一个以下列方式使用 bar() 的函数。

std::string my_func()
{
    const auto &x = bar();
    return x.value;
}

由于 my_func 只包含对 x 的引用,这是否会泄漏内存?还是在 my_func 终止后 x 仍然被清理?

我知道这不是引用的使用方式。但我刚刚意识到这编译得很好,想知道它的语义是什么。

【问题讨论】:

  • 这应该编译吗?你不需要const auto&吗?
  • 你是对的。我的原始代码中有 const auto&。

标签: c++ c++11


【解决方案1】:

但我刚刚意识到这编译得很好

提供的代码不应编译,因为试图将临时分配给左值引用。

错误:从“foo”类型的右值初始化“foo&”类型的非常量引用无效

如果你修复代码,通过

std::string my_func()
{
    const auto &x = bar();
    return x.value;
}

那就没问题了,因为 const 引用将临时的生命周期延长为 const 引用的生命周期。

【讨论】:

  • 对不起...我的原始代码中有 const。
【解决方案2】:

简短回答:不。

更长的答案:在这种情况下,编译器将确保所引用的临时对象将存在于当前范围的末尾。 bar() 按值返回 n 个对象。这将被复制到一个临时的匿名对象中,然后引用将引用该临时对象。

还有其他类似的情况,标准有这个明确的要求:绑定到引用的临时对象一直存在,直到达到当前范围的末尾。

【讨论】:

    【解决方案3】:

    不,字符串被复制到返回值中。 x 引用的对象在函数之后超出范围。

    【讨论】:

    • 这不应该编译
    • 它为我在 gcc 5.2 上编译。这让我感到困惑。
    • 它编译和工作得很好。除了struct foo { std::string value; }之后需要一个分号
    • @pewpew 对,它具有 C++ 标准不支持的“功能”。
    【解决方案4】:

    这不是泄漏,您的引用只是指向由于临时堆栈展开而清理的内存。对象。

    访问 x 将导致未定义的行为。可能是访问冲突。

    【讨论】:

    • 我在我的项目中使用了非常相似的代码行大约一个月,没有任何问题。这让我感到困惑。
    • @KaiMast:很难说为什么它对你有用,但不知道你对类似的意思。例如,当您返回对静态变量的引用时,它将为您工作。如果您想与我们分享您的代码 sn-p,也许我们可以详细说明它为什么对您有用。
    • 引用没有指向被清理的内存,在这段代码的任何地方。
    • @ViktorLiehr 原始代码不应编译,对于固定代码,您的答案不正确。
    • @nos:您认为这里发生了什么以及真正的参考是什么?
    猜你喜欢
    • 1970-01-01
    • 2021-03-23
    • 2021-09-25
    • 2014-12-08
    • 1970-01-01
    • 1970-01-01
    • 2010-09-09
    • 2011-06-16
    相关资源
    最近更新 更多