在 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 的行为本身创建了一个按位副本。
一步一步,代码工作如下:
malloc(sizeof(widget));
在堆上分配一块内存[1],从某个地址开始(我们称它为a),长度为sizeof(widget)
字节。
widget* theWidget = (widget *) malloc(sizeof(widget));
将地址a存储在变量theWidget
中的堆栈[2]中。如果 malloc
在地址 0x00001248
分配了一个块,那么 theWidget
现在包含值 0x00001248
,就像它是一个整数一样。
return theWidget;
现在导致 a 的 value 被 returned,即值 0x00001248
得到写入任何需要 return 值的地方。
theWidget
的地址从未被使用过。因此,不存在访问指向 theWidget
的悬空指针的风险。请注意,如果您的代码 return &theWidget;
,就会出现问题。
[1] 否则可能会失败,并且 return NULL
[2] 或者它可能将其保存在寄存器中
我对这段代码有一种不好的感觉
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 的行为本身创建了一个按位副本。
一步一步,代码工作如下:
malloc(sizeof(widget));
在堆上分配一块内存[1],从某个地址开始(我们称它为a),长度为
sizeof(widget)
字节。widget* theWidget = (widget *) malloc(sizeof(widget));
将地址a存储在变量
theWidget
中的堆栈[2]中。如果malloc
在地址0x00001248
分配了一个块,那么theWidget
现在包含值0x00001248
,就像它是一个整数一样。return theWidget;
现在导致 a 的 value 被 returned,即值
0x00001248
得到写入任何需要 return 值的地方。
theWidget
的地址从未被使用过。因此,不存在访问指向 theWidget
的悬空指针的风险。请注意,如果您的代码 return &theWidget;
,就会出现问题。
[1] 否则可能会失败,并且 return NULL
[2] 或者它可能将其保存在寄存器中