1

こんにちは、私は辞書のようなものを構築する必要があり、私のコードによると、各単語は 100 の意味を持つことができますが、5 つの意味しか持たない可能性があります。ベクトル クラスが非常に簡単で、うまく利用できることはわかっていますが、タスクはほとんど独自のベクトル クラスを構築して、それがどのように機能するかを学習することです。したがって、**意味と他のいくつかのものは同じままで、これが私のコードです。また、メモリリークを引き起こしていることもわかっています。どうすれば適切に削除できますか? :

#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;
}
4

3 に答える 3

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;

したがって、任意のサイズの配列を使用している場合は、デストラクタ内で使用するために、それらをどこかに格納する必要があります。

于 2012-04-26T18:43:03.927 に答える
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 を超える意味を取得した場合 (または一般的にコレクションがいっぱいになった場合) に何をすべきかという問題については、標準的な手法は、サイズが 2 倍の新しい配列を割り当てることです (これは動的であるため実行できます)。既存のコレクションをそのコレクションにコピーしてから、既存のコレクションを破棄します。

于 2012-04-26T18:43:16.523 に答える
0

私は単純なリンクリストを使用します(これは単純化されており、完全ではなく、テストされていません。また、適切なゲッター/セッターなどが必要です):

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;
        }
    }
}
于 2012-04-26T18:53:28.300 に答える