当返回指针时,在堆上创建的对象与本地创建的对象

c++, object created on the heap vs. local - when returning a pointer

本文关键字:创建 对象 指针 返回      更新时间:2023-10-16

这是来自在c#中安全,而不是在c++中,简单返回指针/引用,

:

person* NewPerson(void)
{
  person p;
  /* ... */
  return &p; //return pointer to person.
}

与?

person* NewPerson(void)
{
  person* pp = new person;
  return pp; //return pointer to person.
}

我知道第一个是一个坏主意,因为它将是一个野指针。在第二种情况下,对象在堆上是安全的吗当最后一个引用指向它时,它将超出作用域?

是的,第二种情况是安全的。

但是调用者需要delete返回的指针。您可以将其更改为使用boost::shared_ptr,并且它将在不再使用时被销毁:

boost::shared_ptr<person> NewPerson()
{
    boost::shared_ptr<person> pp = boost::make_shared<person>();
    return pp;
}

如果使用c++ 11,则可以使用std::shared_ptrstd::unique_ptr

这是安全的,对象在返回后仍然是活的。

但是不要期望在c++中对象会自动为你清理。标准c++没有垃圾回收。您需要自己delete对象,或使用某种形式的智能指针。

person* NewPerson(void)
{
  person* pp = new person;
  return pp; //return pointer to person.
}

我知道第一个是一个坏主意,因为它将是一个狂野指针。在第二种情况下,对象在堆上是否安全就像在c#中,当最后一个引用到它时,它就会超出作用域?

第一个正确:它将返回一个指向该函数堆栈上数据的指针,一旦函数结束,该指针将被回收并修改。

在第二种情况下:对象是在堆上创建的,这与执行堆栈是分开的。当函数结束时,堆上的对象是安全的并保持不变。然而,c++不会自动进行垃圾收集,所以如果丢失了对堆对象的所有引用,这将构成内存泄漏——对象的空间在程序结束之前不会被回收。

后者是安全的。然而,c++(通常)不提供垃圾收集,因此您需要为返回对象安排一个显式的delete

就像你说的,第一种情况是不好的,因为指针将无效。至于第二种情况,c++中的内存是不受管理的,你必须自己清理。c++不跟踪普通指针上的引用,这就是std::shared_ptr的作用。