2012-11-07 92 views
1

这两个代码的区别是什么?第一种情况是否有内存泄漏?析构函数问题

没有析构函数定义

class Library 
{ 
private: 
    Book books[50]; 
    int index; 
public: 
    Library() 
    { 

     index=0; 
    } 
}; 

或析构函数定义

class Library 
{ 
private: 
    Book *books; 
    int index; 
public: 
    Library() 
    { 
     books=new Book[50]; 
     index=0; 
    } 
    ~Library() 
    { 
     delete books; 
    } 
}; 
+0

第二个有UB。第一个没有内存泄漏。第二也带来了三/五的规则。 – chris

+0

我是一个初学者,我不知道UB是什么意思或哪个规则是三/五 – laura

+0

“三个C++规则”可以很容易地搜索到 - 而UB的意思是“未定义的行为”,即您的编译器可以选择为了回应你正在做的事情而炸毁你的房子,而且这将是符合标准的。 – Yakk

回答

3
delete books; 

应该是

delete[] books; 

在第二个:books被分配为一个数组,所以米将其作为数组删除。第一个版本没有内存泄漏。

不同之处在于第一种情况下,books的内存被包含在Library的每个实例的分配中,在第二种情况下,它是使用堆分开分配的。

1

首先,第二码应该是

~Library() { 
    delete[] books; 
} 

new必须delete匹配,new[]必须delete[]匹配。

在第一个代码中,Library的每个实例都包含50个Book的实例。复制Library将复制这50个实例。没有内存泄漏。

在第二个代码中,Library的一个实例只包含一个指向书籍的指针。复制实例(没有默认的复制构造函数)只复制指针 - 原始和副本将共享50本书籍,而第二个被破坏的将在已删除的内存上发布delete,这是一个错误。

+0

@Benjamin感谢编辑,我打字的速度比想象的更快...... – Angew

1
~Library() 
{ 
    delete[] books; 
} 

是一个合适的解决方案。有在你的代码免费可能出现的问题,您可以考虑:

1)请使用在第二种情况下初始化列表

2)你真的需要做的指针?不是一个本地对象吗?(我猜你的书不会超过堆栈大小)。看看你在开始创建它的代码并在最后删除。记住堆栈更快,更安全。

还要熟悉valgrind,它是一个非常棒的工具。检查cppcheck是否会帮助你。在Ubuntu中“sudo apt-get install cppcheck”。