【问题标题】:Dynamic Memory Allocation for Dictionary字典的动态内存分配
【发布时间】:2012-04-26 18:29:34
【问题描述】:

您好,我需要构建类似字典的东西,根据我的代码,每个单词可以有 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;
}

【问题讨论】:

  • 你的析构函数中有错字。
  • 正确的解决办法是改用std::multimap&lt;std::string, std::string&gt;

标签: c++ memory dynamic allocation


【解决方案1】:

当您使用 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;

因此,当您拥有任意大小的数组时,您必须将它们存储在某个地方以便在析构函数中使用它们。

【讨论】:

  • 嗨塞巴斯蒂安感谢您的回复,我用w​​hile循环解决了删除部分,与您的方法类似。我尝试实现与您的第一部分类似的东西,但它没有用,这里的问题是我不知道“大小”在我的情况下要多长时间?
  • 我也不知道。这取决于,例如,如果你必须实现类似 vector 的东西,你就必须重新分配内存。也许那么分配更多是好的,你必须保存当前分配的大小。对于重新分配,您必须先new,然后复制并删除旧指针。
  • 我试图用一个指向指针的 **temp_meanings 指针来实现它,但它没有用......我有 3-4 个 for 循环,用于复制和删除然后重新分配......可能是循环太复杂了,某处有错误..我尝试使用MS Visual Studio 2010的调试器,但它很糟糕..还有什么提示吗?
  • 也许写一个关于这个特定主题的新问题,包括一些(仅相关部分)代码并再次提问。
【解决方案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 个含义(或者通常当你的集合已满时)该怎么办的问题,标准技术是分配一个大小为两倍的新数组(你可以这样做,因为它是动态),将您现有的集合复制到该集合中,然后处置您现有的集合。

【讨论】:

    【解决方案3】:

    我会使用一个简单的链表(这是简化的,不完整且未经测试;还应该有适当的 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;
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-13
      • 1970-01-01
      • 2021-02-15
      • 2013-07-01
      相关资源
      最近更新 更多