2012-04-26 266 views
1

嗨,我需要建立一個像字典一樣,根據我的代碼每個單詞可以有100個含義,但也許它只有5個含義,那麼我將分配95額外的空間沒有或可能它有超過100個含義,那麼程序會崩潰,我知道矢量類很容易,可以很好地使用,但任務幾乎建立我自己的矢量類,以瞭解它是如何工作的。因此,**意義和其他一些東西保持不變,這裏是我的代碼,也知道我造成內存泄漏,我該如何正確刪除? :字典的動態內存分配

#include <iostream> 
#include <string> 
#include <cstring> 
using namespace std; 

class Expression { 

    char *word_with_several_meanings; // like "bank", "class" 
    char **meanings; // a pointer to a pointer stores all meanings 
    int meanings_ctr; // meanings counter 

    //-----------FUNCTIONS------------------------------------------------ 
public: 
    void word(char* = NULL); 
    void add_meaning(char* = NULL); 
    char* get_word(); 
    int get_total_number_of_meanings(); 
    char* get_meaning(int meanx = 0); 
    Expression(int mctr = 0); // CTOR 
    ~Expression(); // DTOR 
}; 

    Expression::Expression(int mctr) { 
    meanings_ctr = mctr;   // Setting the counter to 0 
    meanings = new char * [100]; // Allocate Space for 100 meanings 
} 

Expression::~Expression() { 
delete [] meanings; // Deleting the memory we allocated 
delete [] word_with_several_meanings; // Deleting the memory we allocated 
} 

void Expression::word(char *p2c) 
{ 

    word_with_several_meanings = new char[strlen(p2c)+1]; 
// copy the string, DEEP copy 
    strcpy(word_with_several_meanings, p2c); 
} 

void Expression::add_meaning(char *p2c) 
{ 

    //meanings = new char * [meanings_ctr+1]; 
    meanings[meanings_ctr] = new char[strlen(p2c)+1]; 
    strcpy(meanings[meanings_ctr++],p2c); 


} 

char * Expression::get_meaning(int meanx) 
{ 

    return *(meanings+meanx); 

} 

char * Expression::get_word() 
{ 

    return word_with_several_meanings; 

} 

int Expression::get_total_number_of_meanings() 
{ 

    return meanings_ctr; 

} 

int main(void) { 
    int i; 
    Expression expr; 
    expr.word("bank "); 
    expr.add_meaning("a place to get money from"); 
    expr.add_meaning("b place to sit"); 
    expr.add_meaning("4 letter word"); 
    expr.add_meaning("Test meaning"); 
    cout << expr.get_word() << endl; 

    for(int i = 0; i<expr.get_total_number_of_meanings(); i++) 
      cout << " " << expr.get_meaning(i) << endl; 
    Expression expr2; 
    expr2.word("class"); 
    expr2.add_meaning("a school class"); 
    expr2.add_meaning("a classification for a hotel"); 
    expr2.add_meaning("Starts with C"); 
    cout << expr2.get_word() << endl; 
    for(i = 0; i<expr2.get_total_number_of_meanings(); i++) 
      cout << " " << expr2.get_meaning(i) << endl; 

     Expression expr3; 
    expr3.word("A long test ... "); 
    char str[] = "Meaning_  "; 
    for (int kx=0;kx<26;kx++) 
    { 
      str[8] = (char) ('A'+kx); 
      expr3.add_meaning(str); 
    } 

cout << expr3.get_word() << endl; 
for(i = 0; i < expr3.get_total_number_of_meanings(); i++) 
    cout << " " << expr3.get_meaning(i) << endl; 

    return 0; 
} 
+0

還有就是你的析構函數中的錯字。 – 2012-04-26 18:36:59

+0

我已經爲你糾正它。 – 2012-04-26 18:46:45

+0

正確的解決方法是使用'std :: multimap '代替。 – SigTerm 2012-04-26 19:29:36

回答

2

當您分配與new則您與一個循環,例如分配它的多維陣列

char **x = new char*[size] 
for (int i = 0; i < N; i++) { 
    x[i] = new int[size]; 
} 

所以你也必須刪除它以這種方式:

for (int i = 0; i < N; i++) { 
    delete[] x[i]; 
} 
delete[] x; 

因此,當你遇到你的數組的任意大小你必須給他們一些地方保存析構函數中使用它們。

+0

嗨塞巴斯蒂安感謝您的答覆,刪除部分我用一個while循環解決,類似的方法you.I試圖實現類似於你的第一部分的東西,但它沒有工作,這裏的問題是我不知道多久會「大小「在我的情況? – Anarkie 2012-04-29 10:57:41

+0

我也不知道。這取決於,例如,如果你必須實現像vector這樣的東西,你將不得不重新分配內存。也許那麼分配更多一點是好事,你必須保存當前分配的大小。對於重新分配,您必須先「new」,然後複製並刪除舊的指針。 – 2012-04-29 14:48:19

+0

我試圖用一個** temp_meanings指針指向它,但它沒有工作......我有3-4個循環,用於複製和刪除,然後重新分配......可能循環太複雜了,有一個錯誤的地方..我試圖使用MS Visual Studio 2010的調試器,但它糟透了..任何更多的提示? – Anarkie 2012-04-30 11:09:26

2
delete [] meanings; // Deleting the memory we allocated 

不會擺脫你分配的內存,只有指針本身。

要釋放實際內存,您需要遍歷您的meanings陣列和delete []中的每個元素。

喜歡的東西:

for (int i = 0; i < meanings_ctr; ++i) 
{ 
    delete [] meanings[meanings_ctr]; 
    meanings[meanings_ctr] = NULL; 
} 
delete [] meanings; 

-

有關,如果你得到超過100個含義做什麼的問題(或者一般而言,當您的收藏已滿),標準的方法是分配一個尺寸加倍的新數組(因爲它是動態的,你可以這樣做),將現有的集合複製到那個數組中,然後處理現有的數組。

0

我會使用一個簡單的鏈表(這是簡化的,不完整的,未經檢驗,也應該有適當的getter/setter方法和材料):

class Meaning { 
    char text[20]; 
    Meaning *next; 

    Meaning(const char *text) : next(0) { 
     strcpy(this->text, text); 
    } 
} 

class Word { 
    char text[20]; 
    Meaning *first; 
    Meaning *last; 

    Word(const char *text) : first(0), last(0) { 
     strcpy(this->text, text); 
    } 

    ~Word() { 
     Meaning *m = first, *n; 
     while(m) { 
      n = m->next; 
      delete m; 
      m = n; 
     } 
    } 

    void AddMeaning(const char *text) { 
     if (last) { 
      last = last->next = new Meaning(text); 
     } 
     else { 
      first = last = new Meaning(text); 
     } 
    } 

    void print() { 
     printf("%s:\n\t", text); 
     Meaning *m = first; 
     while (m) { 
      printf("%s, ", m->text); 
      m = m->next; 
     } 
    } 
}