2011-12-10 91 views
2

时,这是从 Safe in C# not in C++, simple return of pointer/reference,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. 
} 

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

+1

这些都不是C#代码。第二个是C++中的内存泄漏,如果你不手动释放它的话。 – CodesInChaos

+0

他们不一样,都是一个坏主意。 –

回答

2

它很安全,返回后对象仍然活着。

但不要指望在C++中自动清理对象。标准C++没有垃圾收集。您需要自己使用delete对象,或者使用某种形式的智能指针。

0

后者是安全的。但是,C++通常不提供垃圾收集,因此您需要安排返回对象的明确delete

0

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

1
person* NewPerson(void) 
{ 
    person* pp = new person; 

    return pp; //return pointer to person. 
} 

我知道,第一个是一个坏主意,因为这将是一个野生 指针。在第二种情况下,对象是否会在堆中安全 - 并且像c#中那样的 在最后一个引用被删除时超出了范围?

更正第一个问题:它将返回一个指向该functin堆栈上数据的指针,该函数完成后将被回收和修改。

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

3

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

但是,调用者将需要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

+0

好的如果被引用的指针设置为0(空)?或者超出范围,就像在c#中一样# – Niklas

+0

如果超出范围,或者您通过调用返回的智能指针上的'reset()'设置为NULL。 – hmjd