我对这段代码感觉不好
widget* GetNewWidget()
{
widget* theWidget = (widget *) malloc(sizeof(widget));
return theWidget;
}
首先,应该永远不应该转换malloc()的结果(我怀疑,在C ++中使用它(?))。
其次,赢得theWidget
在堆栈上分配?
如果是这样,在此函数返回后,调用者试图访问是不是未定义的行为?
有人可以指向解释此问题的权威网址吗?
[更新]我正在考虑这个问题Can a local variable's memory be accessed outside its scope?
答案 0 :(得分:1)
在堆栈上你刚刚分配了一个指针,它与对象本身无关。 :)
我从不使用malloc(它不是C语言,你不应该在C ++中使用它),因此我不确定,但我几乎不相信它的未定义行为。
如果你这样写:$customer = \Stripe\Customer::retrieve($user->stripe_id);
// $customer is now a \Stripe\Customer object
$subscriptions = $customer->subscriptions;
// $subscriptions is now an array of \Stripe\Subscription objects
foreach($subscriptions as $subscription) {
$current_period_end = $subscription->current_period_end;
}
它应该正常工作。
如果使用智能指针,如果你有C ++ 11
,那就更好了widget* theWidget = new widget();
或者在这种情况下,您可以编写更小的代码,如下所示:
std::unique_ptr<widget> GetNewWidget()
{
std::unique_ptr<widget> theWidget(std::make_unique<widget>());
return theWidget;
}
只要唯一指针超出范围,上述版本就会清除内存。 (除非你把它移到另一个unique_ptr)在C ++ 11中阅读有关内存管理的时间是值得的。
答案 1 :(得分:1)
返回指针就像返回int
一样:返回的行为会创建一个按位副本。
malloc(sizeof(widget));
在堆[1]上分配一块内存,从某个地址开始(让我们称之为 a ),并且sizeof(widget)
个字节长。
widget* theWidget = (widget *) malloc(sizeof(widget));
在变量theWidget
的堆栈[2]上存储地址 a 。如果malloc
在地址0x00001248
分配了一个阻止,则theWidget
现在包含值0x00001248
,就好像它是一个整数。
return theWidget;
现在返回 a 的值,即值0x00001248
将被写入预期返回值的任何位置。
绝不使用theWidget
的地址。因此,不存在访问指向theWidget
的悬空指针的风险。请注意,如果您的代码为return &theWidget;
,则会出现问题。
[1]或者它可能会失败,并返回NULL
[2]或者它可能会将其保存在寄存器中