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

时间:2015-08-28 14:52:27

标签: c++ stack allocation c++03

我对这段代码感觉不好

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

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

其次,赢得theWidget在堆栈上分配?

如果是这样,在此函数返回后,调用者试图访问是不是未定义的行为?

有人可以指向解释此问题的权威网址吗?

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

2 个答案:

答案 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一样:返回的行为会创建一个按位副本。

步骤,步骤,代码的工作原理如下:

  1. malloc(sizeof(widget));

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

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

    在变量theWidget的堆栈[2]上存储地址 a 。如果malloc在地址0x00001248分配了一个阻止,则theWidget现在包含值0x00001248,就好像它是一个整数。

  3. return theWidget;

    现在返回 a ,即值0x00001248将被写入预期返回值的任何位置。

  4. 绝不使用theWidget的地址。因此,不存在访问指向theWidget的悬空指针的风险。请注意,如果您的代码为return &theWidget;,则会出现问题。

    [1]或者它可能会失败,并返回NULL

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