2012-04-26 129 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; 
     } 
    } 
}