0

コンストラクターでの私の目標は次のとおりです。

ファイルを開き、特定の文字列 ("%%%%%") の間に存在するすべてのものを読み取ります。読み取った各行を変数 (履歴) にまとめます。最後の変数を char (_stories) 型の double ポインターに追加します。ファイルを閉じます。

ただし、strcat を使用するとプログラムがクラッシュします。しかし、理由がわかりません。何時間も試してみましたが、結果が得られませんでした。:/

コンストラクターのコードは次のとおりです。

Texthandler::Texthandler(string fileName, int number) 
        : _fileName(fileName), _number(number)  
{
    char* history = new char[50];

    _stories = new char*[_number + 1]; // rows
    for (int j = 0; j < _number + 1; j++)
    {
        _stories[j] = new char [50]; 
    }
        _readBuf = new char[10000]; 

    ifstream file;
    int controlIndex = 0, whileIndex = 0, charCounter = 0;

    _storieIndex = 0;

    file.open("Historier.txt"); // filename 
    while (file.getline(_readBuf, 10000))
    {
        // The "%%%%%" shouldnt be added to my variables
        if (strcmp(_readBuf, "%%%%%") == 0)
        {
        controlIndex++;
        if (controlIndex < 2)
        {
            continue;
        }
    }

    if (controlIndex == 1)
    {
        // Concatenate every line (_readBuf) to a complete history
        strcat(history, _readBuf);
        whileIndex++;
    }

    if (controlIndex == 2)
    {
        strcpy(_stories[_storieIndex], history);

        _storieIndex++;
        controlIndex = 1;
        whileIndex = 0;
        // Reset history variable
        history = new char[50];

    }
}
file.close(); 
}

私もstringstreamで結果なしで試しました..

編集: エラー メッセージを投稿するのを忘れました:「Step3_1.exe の 0x6b6dd2e9 (msvcr100d.dll) で未処理の例外: 0xC00000005: アクセス違反の書き込み場所 0c20202d20.」すると、「strcat.asm」という名前のファイルが開きます。

よろしくロバート

4

2 に答える 2

2

0c20202d20ポインタの 1 つが(いくつかのスペースと-記号)であるという事実によって証明されるように、スタックのどこかでバッファ オーバーフローが発生しました。

それはおそらく次の理由によるものです。

char* history = new char[50];

そこに入れようとしているものに対して十分な大きさではありません (または、文字で終了する C 文字列として正しく設定されていません\0)。

それぞれ最大 10K の複数のバッファを 50 バイトの文字列に連結できると考える理由は完全にはわかりません :-)

于 2013-05-17T08:42:04.240 に答える
1

strcatnull で終了charする配列で動作します。ラインで

strcat(history, _readBuf);

historyは初期化されていないため、null ターミネータを持つことは保証されていません。プログラムは、'\0'バイトを探して割り当てられたメモリを超えて読み取る可能性があり_readBuf、この時点でコピーを試みます。割り当てられたメモリを超えて書き込むhistoryと、未定義の動作が呼び出され、クラッシュする可能性が非常に高くなります。

null ターミネータを追加した場合でも、historyバッファは よりもはるかに短くなり_readBufます。これにより、メモリの上書きが発生する可能性が非常に高くなります。history少なくとも_readBuf.

std::stringあるいは、これは C++ なので、 C スタイルのchar配列の代わりに使用しないのはなぜですか?

于 2013-05-17T08:42:13.813 に答える