在 C++ 2003 中重新调整本地分配的对象

Retuning locally allocated object in C++ 2003

我对这段代码有一种不好的感觉

widget* GetNewWidget()
{
   widget* theWidget = (widget *) malloc(sizeof(widget));
   return theWidget;
}

首先,永远不要转换 malloc() 的结果(我怀疑也不应该在 C++ 中使用它(?))。

其次,theWidget不会分配到栈上吗?

如果是这样,那么在这个函数之后尝试访问的调用者会不会是未定义的行为returns?

谁能指出权威的 URL 来解释这个?


[更新]我在想这个问题Can a local variable's memory be accessed outside its scope?

在栈上你只是分配了一个指针,它与对象本身无关。 :)

我从不使用 malloc(这是 C 的东西,你不应该在 C++ 中使用它),因此我不确定,但我几乎不相信这是未定义的行为。

如果你这样写:widget* theWidget = new widget(); 它应该可以正常工作。

如果你有 C++11,如果你使用智能指针就更好了

std::unique_ptr<widget> GetNewWidget()
{
   std::unique_ptr<widget> theWidget(std::make_unique<widget>());
   return theWidget;
}

或者在这种情况下,您可以编写更小的代码,如下所示:

std::unique_ptr<widget> GetNewWidget()
{
   return std::make_unique<widget>();
}

以上版本将在唯一指针超出范围时立即清除内存。 (除非你把它移到另一个 unique_ptr)值得花一些时间阅读 C++11 中的内存管理。

总结:这段代码非常好

返回指针就像 returning 一个 int:returning 的行为本身创建了一个按位副本。

一步一步,代码工作如下:

  1. malloc(sizeof(widget));

    在堆上分配一块内存[1],从某个地址开始(我们称它为a),长度为sizeof(widget)字节。

  2. widget* theWidget = (widget *) malloc(sizeof(widget));

    将地址a存储在变量theWidget中的堆栈[2]中。如果 malloc 在地址 0x00001248 分配了一个块,那么 theWidget 现在包含值 0x00001248,就像它是一个整数一样。

  3. return theWidget;

    现在导致 avalue 被 returned,即值 0x00001248 得到写入任何需要 return 值的地方。

theWidget 的地址从未被使用过。因此,不存在访问指向 theWidget 的悬空指针的风险。请注意,如果您的代码 return &theWidget;,就会出现问题。

[1] 否则可能会失败,并且 return NULL

[2] 或者它可能将其保存在寄存器中