2011-06-28 25 views
8

我有以下代码,我想知道delete b在这里是否有必要? 我的操作系统会自动清除分配的内存区域吗?在析构函数中是否需要删除?

class A 
{ 
    B *b; 

    A() 
    { 
     b = new B(); 
    } 

    ~A() 
    { 
     delete b; 
    } 
}; 

非常感谢。

+5

['A'还需要一个拷贝构造函数和赋值运算符](http://stackoverflow.com/questions/4172722/what-is-the-rule-of-reeree)。 – GManNickG

回答

10

是的,你必须deletenew您拥有创建的每个对象。在这种情况下,它看起来像class A拥有class B的实例,并负责调用delete

使用智能指针来管理实例生存期会更好。另外请注意,您必须在class A中实施或禁止赋值运算符和复制构造函数,以防止浅拷贝会导致很大麻烦的对象。

1

它的写作方式当然是必要的。但即使使用delete,班级也会因为管理资源而受到严重破坏,但不会遵循the rule of three

也就是说,手动内存管理几乎没有任何理由 - 很少有。这可能是因为你要么只是有一个B对象作为成员变量,或者你应该使用智能指针,就像QScopedPointer

struct A 
{ 
    QScopedPointer<B> b; 
    A() : b(new B()) { } 

    // No ~A() needed; when the A object is destroyed, QScopedPointer ensures 
    // that the B object pointed to by the member 'b' is destroyed and deleted. 
}; 

你要确保你有a good introductory C++ book这样就可以了学习如何编写正确的C++程序。

5

很可能您的操作系统将释放分配的内存 - 但这是在程序退出时完成的。长时间运行的程序会遇到内存问题。

将动态指针用于动态全局对象始终是个好主意。这些会为你做所有删除的东西。

  • 的std :: auto_ptr的
  • 的boost :: shared_ptr的
  • 的boost :: scoped_ptr的
1

只有当过程结束这将清除该地区,但该地区仍保持分配所有的时间直到那时,这意味着memory leak

2

如果您拨打新电话,始终建议您进行相应的删除。

至于操作系统删除你的内存..是的,它会发生,但只有在整个过程终止后(即你的应用程序退出)。只有这样操作系统才能回收所有内存和其他资源。

第三,只在必要时尝试使用新/删除。在你的情况下,你可以写

class A 
{ 

B b; 

    A() {} 

    ~A() {} 

}; 

它会有同样的效果,你避免了额外的动态内存分配。

0

b成员将被分配在堆上。确实,操作系统将释放堆占用的所有内存;但是这只会发生一次:程序退出

所以,如果你没有释放分配的堆块的时间,他们变得不使用(通常在某些对象的析构函数),你有冒险得到memory leak

因此,答案基本上是:,你必须手动调用delete,因为内存不会被自动的尽快释放(虽然智能指针将帮助你实现类似的东西)。

0

任何你分配的new你应该用delete免费,否则你的应用程序会有内存泄漏。

在大多数现代操作系统(当然人们通常在台式计算机上运行的操作系统)中,流程使用的任何内容都会在流程结束时被清理,因此如果您忘记delete,那么无论如何内存都将被释放。但是你应该依靠这个。

很久以前,我在C编程了Amiga。它的操作系统比现在的操作系统要复杂得多。如果你要分配内存而不释放它,那么即使在过程结束后,它也会保持分配状态,直到你关闭或重新启动计算机。内存泄漏是一个更严重的问题。

1

资源管理不仅仅是释放内存。是的,大多数平台都会在流程结束时分配任何内存,并且内存足够便宜,可能您一段时间都不会注意到。但文件b是否保持打开状态,或者它将在其析构函数中解锁的互斥锁?在用完内存之前,您可能会遇到让对象超出其有用性的问题。

0

1)长时间运行的应用程序会遇到问题,因为操作系统只能在应用程序停止运行时回收内存。

2)delete b;也导致指向B实例的析构函数运行。否则它将永远不会运行,因为再也找不到它了。那个析构函数可能会做一些重要的事情。

相关问题