从工厂函数返回右值引用时堆/内存损坏

Posted

技术标签:

【中文标题】从工厂函数返回右值引用时堆/内存损坏【英文标题】:Heap/memory corruption when returning rvalue reference from factory function 【发布时间】:2014-10-11 00:00:45 【问题描述】:

我有这样的课:

class CObj

public:
   CObj(std::string const& str) : m_str(str) 

   static CObj&& Current()
   
      CObj uxid"test";
      return std::move(uxid);
   

private:
   std::string m_str;
;

我是这样使用的:

CObj objCObj::Current();

obj 内部的 std::string 已损坏/无效。我希望将临时从工厂移出并移动初始化obj。我做错了什么?

【问题讨论】:

返回对本地的引用对于右值引用和左值引用一样糟糕。只需按值返回 static CObj Current() return "test"; 并让编译器为您处理移动。 【参考方案1】:

Current 的返回类型是引用类型。您正在返回对本地对象的引用,该对象将在被调用者尝试访问它以构造 obj 之前被销毁,从而导致未定义的行为。返回类型是右值引用这一事实与这一事实无关,问题与左值引用返回类型相同。

如果你想从一个函数中返回一个新创建的对象,你应该按值返回:

static CObj Current() 
  return "test";

或:

static CObj Current() 
  CObj uxid"test";
  // do stuff with uxid here.
  return uxid;

按值返回的局部变量将自动移动,尽管编译器更有可能应用返回值优化并直接在返回值中构造对象,而不进行任何移动或复制。

【讨论】:

以上是关于从工厂函数返回右值引用时堆/内存损坏的主要内容,如果未能解决你的问题,请参考以下文章

从函数返回的左值引用实际上是右值吗(从调用者的角度来看)?

重新理解C11的右值引用

格式工厂 右值引用

C11新特性右值引用&&

右值引用,移动语义,完美转发

我应该通过右值引用返回一个右值引用参数吗?