0

この関数を何度も (正確には何回かは不明) 実行した後、単純なメモリ割り当てでエラーを検出します。なんでいきなりこうなるの?GDB で奇妙なことに気付きました。それを呼び出す関数では、通常、wrd には 6 桁の 16 進数値 (たとえば、wrd = 0x605140) がありますが、クラッシュする呼び出しでは、16 進数値は 2 桁しかありません。(ワード = 0x21)。wrd->length も確認しましたが、3 です。

クラッシュするラインは...

char *word_temp = malloc(wrd->length * sizeof(char));

編集:

wrdを作成するコードは次のとおりです...

while(fgets(input, 100, src) != 0)
{
    int i = 0;
    while(input[i] != '\0')
    {
        i++;
    }

    struct word *wrd = malloc(sizeof(struct word));
    wrd->letters = input;
    wrd->length = i;

オーバーフローが発生した場合、どうすれば修正できますか?

4

1 に答える 1

0

wrd->length終端の が含まれていないように見えます'\0'

修正 1、次のword_tempように割り当てます。

char *word_temp = malloc( wrd->length + 1 );

修正 2、長さカウント ループを変更して '\0' を含めます。

int i = 0;
while(input[i++] != '\0') {}

これは、質問のコードよりも 1 回増加します。これは、空iの場合を考えると簡単にわかります。input

両方ではなく、修正 1 または修正 2 のいずれかを実行する必要があることに注意してください。コードの残りの部分で機能するものを選択してください。


おそらく、次の行に 2 番目の問題があります。

wrd->letters = input;

入力をコピーするのではなく、ポインターをコピーします。inputの内容を変更wrd->lettersすると、同じメモリ位置を指しているため、 の内容も変更されます。また、inputがローカルの char 配列の場合、スコープ外にwrd->lettersなるとダングリング ポインターになり、他のデータによって上書きされ、その後変更するとメモリが破損します。

可能な修正(コードの残りの部分に応じて)は、次を使用することstrdupです:

wrd->letters = strdup(input);

現在はヒープから割り当てられていることに注意してください。完了したら、忘れずに行う必要があります

free(wrd->letters);

0x21についてwrdは、メモリが破損しているか、実際には 2 つの個別のwrd変数があり、1 つが初期化されていないことを示しています。

たとえば、wrdは関数のパラメーターstruct word *wrdである可能性があります。この場合、関数のローカル値のみを変更すると、呼び出し元に渡されません。呼び出し元のポインターを変更するには、ポインターへのポインターが必要です。struct word **wrd次に、(*wrd) = malloc...and(*wrd)->letters...などを実行します。

于 2013-04-08T14:44:13.703 に答える