0

只是想澄清一下 shared_ptr

int main(){
   typedef std::tr1::shared_ptr<Foo> _foo;

   _foo obja(new Foo());
   Foo *objb = obja.get(); 

   // delete objb; //deleting objb will throw double free or corruption
   return 0;
}

在上面的代码中,如果objb没有被删除或释放,是否存在内存泄漏?最终,obja将超出范围并释放自己。由于objbobja指向同一个实例,这是否意味着不需要释放objb

上面是不是和这个一样:

Foo *obja = new Foo();
Foo *objb;

objb = obja;
delete obja;
4

4 回答 4

6

不,没有泄漏。原始指针没有任何所有权语义,并且get从 a 中提取原始指针也不会shared_ptr增加引用计数。

当共享指针超出示例中的范围时,指向的对象将被销毁。正如您已经注意到的那样,手动删除它会导致未定义的行为。

于 2013-03-06T14:27:12.457 回答
4

在上面的代码中,如果 objb 没有被删除或释放,是否存在内存泄漏?

Foo对象归obja共享指针所有。通过这样做.get(),您可以检索一个“哑”,观察指针,该指针对指向对象的生命周期没有任何影响。您只需要注意不要在指向的对象不再存在后取消引用它,否则您将获得未定义的行为。

由于 objb 和 obja 指向同一个实例,这是否意味着不需要释放 objb?

不需要释放objb,因为当obja超出范围时,其析构函数将delete拥有对象。如果你这样做了delete objb,你会通过尝试两次删除一个对象来获得未定义的行为。

上面是不是和这个一样:

我想有人可以这么说,是的。

于 2013-03-06T14:29:10.327 回答
1

不,没有泄漏。 obja仍然拥有内存,并且obja在范围退出时被销毁时被释放。获取指针并不等同于释放其所有权(qv release())。因此,您通过 获得了一个弱(非拥有)指针get(),只要实际所有者存在,它就有效,但如果原始指针比拥有的指针寿命长,则它是一个悬空指针shared_ptr

于 2013-03-06T14:28:43.277 回答
0

我认为上面的大多数答案表明他们不明白你的困惑在哪里。
所以 C 和 C++ 中的指针只是一个内存地址。当您将一个原始指针“复制”到另一个原始指针时,您会使它们都指向相同的地址:

int *ptr1 = new int(); // points to memory at address lets say 1234;
int *ptr2 = ptr1; // now also points to 1234
*ptr1 = 10; // modify int where ptr1 points to
std::cout << *ptr2 << std""endl; // print 10 as ptr2 points to the same place as ptr1
delete ptr1; // I do not need memory at address 1234 anymore
delete ptr2; // I do not need memory at address 1234 again, error double deletion

您可以将指针视为数字,当您将一个指针分配给另一个指针时,您只需复制该数字,该地址处的内存不会发生任何事情。

于 2013-03-06T15:28:35.187 回答