-1

パイプから文字を読み取り、それらを結果文字列に入れることでマージを実装しようとしています。セグメンテーション エラーが発生し続け、問題の原因をデバッグするのに苦労しています。この関数の呼び出しを削除すると問題が解決するので、ここで何かが間違っていると感じています。

MAX_LENGTH は 1024 に設定されており、約 30 文字しか並べ替えていないので、余裕があるはずです。

int merge(char *result, int *leftpipefd, int *rightpipefd) {
char left[MAX_LENGTH/2];
char right[MAX_LENGTH/2];
int leftpos = 0;
int rightpos = 0;
int resultpos = 0;

read(leftpipefd[READ_END], left, MAX_LENGTH/2);
read(rightpipefd[READ_END], right, MAX_LENGTH/2);

int leftlen = strlen(left);
int rightlen = strlen(right);

while (leftpos < leftlen || rightpos < rightlen) {
    if (leftpos < leftlen && rightpos < rightlen) {
        if (left[leftpos] <= right[rightpos]) {
            result[resultpos] = left[leftpos];
            resultpos++;
            leftpos++;
        } else {
            result[resultpos] = right[rightpos];
            resultpos++;
            rightpos++;
        }
    } else if (leftpos <  leftlen) {
        result[resultpos] = right[rightpos];
        resultpos++;
        rightpos++;
    } else if (rightpos <  rightlen) {
        result[resultpos] = left[leftpos];
        resultpos++;
        leftpos++;
    }
}

return EXIT_SUCCESS;
}

誰かが私が間違っていることを見ることができますか?

4

2 に答える 2

0

長さ N のバッファーに N 文字を読み込む場合、関数が適切に機能することをどのように期待しますか...終了文字用のスペースが必要であるためstrlen、少なくとも のバッファーが必要です。それがなければ、次に何が起こるか誰にもわかりません...N+1\0

于 2013-02-13T02:22:28.770 に答える
0

いくつかのこと...

http://linux.die.net/man/2/readから...

read() は、ファイル記述子 fd から buf から始まるバッファーに最大 count バイトの読み取りを試みます。count が 0 の場合、read() は 0 を返し、それ以外の結果はありません。count が SSIZE_MAX より大きい場合、結果は規定されていません。

MAX_LENとは?SSIZE_MAXより大きいか? もしそうなら、あなたは未定義の振る舞いをしています。

read() に入力がない場合、何も読み取れません...そして、初期化していないバッファは変更されていません。バッファを初期化する必要があります。

同じページから...

エラーの場合は -1 が返され、errno が適切に設定されます。

読み取りが失敗した場合、バッファは未定義/未初期化のままですが、この状況を検出/処理しません。read() の直後にエラー処理コードが必要です。

また、同じ man ページには、read() からのバッファーが null で終了するというインジケーターはありません。Floris が指摘しているように、これは strlen() が割り当てられたバッファの最後を超えて読み取りを続ける可能性があることを意味します。

while (leftpos < leftlen || rightpos < rightlen) {

この行は間違っている可能性があります。leftpos >= leftlen で rightpos < rightpos の場合、while ブロックの本体に入ります。おそらく、その方法で無効なメモリにアクセスし始めるでしょう。本当に必要&&ですか?

于 2013-02-13T02:22:53.250 に答える