0

私はObjective-C/CからやってくるC++を学んでいます。ダミーのプロジェクトでは、/usr/share/dict/wordsMacOSXマシンに保存されているファイルから単語をロードしたいと思います。

アイデアは、ファイルをロードして各単語を配列に入れることなのでarray、タイプはstringです。

しかし、配列でダイナミックメモリを正しく操作するのに問題があります-とを使用newdeleteます。誰かが助けてくれるなら、私は以下のコードのいくつかを追加しました...

そのため、メモリエラーが発生します。

word:: A
word:: a
word:: aa
word:: aal
definitions(2758) malloc: *** error for object 0x100103b90: incorrect 
checksum for freed object - object was 
probably modified after being freed.
*** set a breakpoint in malloc_error_break to debug

単語を読み込む:

string* Definition::loadWords()
{
    int arrayLength = 0;

    arrayOfWords = new string[arrayLength];

    ifstream file;

    file.open("/usr/share/dict/words");

    if(file.is_open())
    {
        while(file.good()){
            string word;
            getline( file, word );
            this->addWord(word, arrayOfWords, &arrayLength);
        }

    }

    file.close();

    cout << endl << "There are " << arrayLength << " words" << endl;

    return arrayOfWords;
};

配列に単語を追加します。

void Definition::addWord(string newWord, string currentArray[], int* arrayLength)
{
    cout << endl << "word:: " << newWord;

    string *placeholderArray = new string[*arrayLength + 1];
    placeholderArray[*arrayLength + 1] = newWord;

    for(int i = 0; i < *arrayLength; i++){
        placeholderArray[i] = currentArray[i];
    }

    (*arrayLength)++;

    currentArray = placeholderArray;

    delete [] placeholderArray;
}
4

3 に答える 3

1

私が最初に見ることができるのはこれです:

placeholderArray[*arrayLength + 1] = newWord;

配列の終わりを超えて要素を追加しています。配列には0からインデックスが付けられます。たとえば、配列の長さが5の場合、配列の最後の要素はインデックス4になります。したがって、行は次のようになります。

placeholderArray[*arrayLength] = newWord;

その後、次のようにしてアレイを削除します。

currentArray = placeholderArray;

delete [] placeholderArray;

プレースホルダーアレイを指すようにcurrentArrayを設定し、それを削除しているだけなので。

また、参照による受け渡しは、ポインタによる受け渡しよりもはるかに優れています。だからこれではなく:

void Definition::addWord(string newWord, string currentArray[], int* arrayLength)

これを使って:

void Definition::addWord(string newWord, string currentArray[], int& arrayLength)

使用するたびに値を取得するために、常に*を使用する必要はありません。

参照の使用に関するチュートリアルは次のとおりです。http: //www.learncpp.com/cpp-tutorial/73-passing-arguments-by-reference/

また、時間と労力を節約し、配列ではなくベクトルとstlコンテナーを後でではなく早く使用する方法を学びます。

ベクトルを使用するためのチュートリアルは次のとおりです。http: //www.codeguru.com/cpp/cpp/cpp_mfc/stl/article.php/c4027/C-Tutorial-A-Beginners-Guide-to-stdvector-Part-1.htm

于 2013-02-19T02:48:39.530 に答える
1
currentArray = placeholderArray;

これにより、placeholderArrayがcurrentArrayにエイリアスされます。だから、あなたが電話するとき...

delete [] placeholderArray;

..currentArrayが指しているものを削除しています。

于 2013-02-19T02:46:52.553 に答える
1

ここでは、配列内の値ではなく、単にポインタを割り当てています。

currentArray = placeholderArray;

そして、ここで、上記のポインタが指すスペースを解放します。

delete [] placeholderArray;

次に解放されたメモリスペースから読み取ると、未定義の動作が発生します。


C ++でCスタイルの配列を使用する代わりに、std::vectorとそのresize()関数を使用します。さらに良いことに、アプリケーションはpush_back()それぞれを呼び出すだけで、関数newWordの必要性全体が不要になりますaddWord()

于 2013-02-19T02:47:03.107 に答える