2014-01-08 67 views
0

我有一個非常簡單的虛擬節目QVector內存管理

levenshteindb.h:

#ifndef LEVENSHTEINDB_H 
#define LEVENSHTEINDB_H 

#include <QVector> 
#include "levenshteindbnode.h" 

class LevenshteinDB 
{ 
    unsigned size; 
    QVector<LevenshteinDBNode> nodes; 
    void realloc_rows(unsigned node); 

public: 
    LevenshteinDB(); 
    ~LevenshteinDB(); 
    void add_word(); 
}; 

#endif // LEVENSHTEINDB_H 

levenshteindb.cpp:

#include "levenshteindb.h" 
#include <cstring> 
#include <cstdio>  

LevenshteinDB::LevenshteinDB() 
{ 
    size=15; 
    nodes.append(LevenshteinDBNode(size)); 
} 

LevenshteinDB::~LevenshteinDB() 
{ 
} 


void LevenshteinDB::add_word() 
{ 
    nodes.append(LevenshteinDBNode(size)); 
} 


void LevenshteinDB::realloc_rows(unsigned newsize) 
{ 
    for(unsigned i=0;i<nodes.size();i++) 
     nodes[i].realloc(newsize); 
} 

levenshteindbnode.h:

#ifndef LEVENSHTEINDBNODE_H 
#define LEVENSHTEINDBNODE_H 

struct LevenshteinDBNode 
{ 
    LevenshteinDBNode(); 
    LevenshteinDBNode(unsigned size); 
    ~LevenshteinDBNode(); 
    unsigned *row; 
    void realloc(unsigned newsize); 
}; 

#endif // LEVENSHTEINDBNODE_H 

levenshteindbnode.cpp:

#include "levenshteindbnode.h" 

LevenshteinDBNode::LevenshteinDBNode(){}; 

LevenshteinDBNode::LevenshteinDBNode(unsigned size) 
{ 
    row = new unsigned[size]; 
} 

LevenshteinDBNode::~LevenshteinDBNode() 
{ 
    delete[] row; 
} 

void LevenshteinDBNode::realloc(unsigned newsize) 
{ 
    delete[] row; 
    row=new unsigned[newsize]; 
} 

main.cpp中:

#include "levenshteindb.h" 

int main() 
{ 
    LevenshteinDB *trie = new LevenshteinDB(); 
    trie->add_word(); 
    trie->add_word(); 
    trie->add_word(); 
    delete trie; 
} 

的崩潰,似乎有一個巨大的(相比於程序本身分配的內存)內存泄漏,但我真的不明白什麼是錯的.. 我使用QT 5.2

回答

3

您需要了解the rule of three

發生了什麼事也就是當你做

nodes.append(LevenshteinDBNode(size)); 

您創建一個臨時LevenshteinDBNode objectm,然後將其複製,導致兩個對象有兩個指向相同的內存。然後臨時對象被銷燬多少追隨者會導致你的析構函數被調用,有多少追隨者,並刪除你分配的內存。現在你有對象的副本的指針被刪除的記憶。

你需要實現一個拷貝構造函數有多少追隨者不分配的內存的所謂的深拷貝。


你在你的代碼alsohave一個更加微妙的錯誤,那你不初始化在LevenshteinDBNode默認的構造函數指針。這意味着,如果你有一個默認的構造的情況下,指針將有一個不確定的值,在現實中,它會指向一個隨機位置。這會導致不確定的行爲,如果默認構造的實例,然後破壞當您嘗試delete此隨機指針。您需要在默認的構造函數指針初始化爲nullptr

+0

謝謝您的回答,這無疑擊中了問題(一個或多個),只有一個我想問其他的事情,我應該怎麼做才能解決這個問題?我的意思是,對於LevenshteinDBNode thatmakes對象的深層副本我可以定義一個拷貝構造函數,但以這種方式時,我稱之爲「nodes.append(LevenshteinDBNode(大小))」的內存分配兩次構造一個對象,這似乎對我來說不是很有效,所以我需要創建兩個方法init()和free()的手動分配和釋放「行」(並在構造函數中刪除和析構函數的任何「新」和「刪除」)? – woggio

+1

@ user2318607不幸的是它是如何工作的。如果你有一個C++編譯器能夠11(和Qt被更新爲使用新的C++ 11個功能),你可以使用[移動語義(http://stackoverflow.com/a/3109981/440558)避免在某些情況下複製。但你仍然需要做一個拷貝構造了衆多的追隨者如何第二分配和數據的副本。 –

+4

我認爲你可能OOK定義軸QVector LevenshteinDBNode ::行。 – nikitoz