1

これは、ファイルから文字列を入力し、文字列を1 つずつLineBufにプッシュし、1 つの文字列をLineBufにプッシュした後、LineBufを出力し、LineBufを空にするプログラムです。

これは私のコードです:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char *LineBuf = NULL;
int BufLen = 0;

void PushToBuf(char c)
{
    LineBuf = (char *)realloc(LineBuf, (BufLen+2)*sizeof(char));
    LineBuf[BufLen] = c;
    BufLen++;
    LineBuf[BufLen] = '\0';
}

int main()
{
    char temp[20];
    int i;
    FILE *fp;
    fp = fopen("input", "r");

    while (fgets(temp, 20, fp) > 0)
    {
        /*Push temp into buf*/
        for (i = 0; i < strlen(temp); i++)
            PushToBuf(temp[i]);

        /*print buf*/
        printf("%s\n", LineBuf);
        printf("%d\n", BufLen);

        /*make buf empty*/
        free(LineBuf);
        BufLen = 0;
    }
    return 0;
}

これは私の入力ストリームです:

This is a test. Good evening
bye~

これは実行結果です:

This is a test file
19
. Good evening

15
 glibc detected  ./a.out: double free or corruption (fasttop): 0x00000000023fa250 

======= Backtrace: =========

/lib/libc.so.6(+0x775b6)[0x7f2ad01bf5b6]
/lib/libc.so.6(cfree+0x73)[0x7f2ad01c5e83]
./a.out[0x400868]
/lib/libc.so.6(__libc_start_main+0xfd)[0x7f2ad0166c4d]
./a.out[0x400699]
4

4 に答える 4

1

これは LineBuf を空にしません。LineBuf のストレージ領域を解放します。後で LineBuff を再割り当てすると、解放されたスペースを再割り当てしようとします。

    /*make buf empty*/
    free(LineBuf);

問題を解決するには、free を while ループの外に移動します。保存するすべてのデータを null に設定して、空きバフを空にします。

for(int i =0; i < BuffLen) LineBuf[i]='\0';

于 2011-12-17T14:47:50.637 に答える
1

あなたは'dポインタをしようとしてreallocいます。freeあなたはそれを行うことはできません!

于 2011-12-17T14:48:56.340 に答える
1

仕組みrealloc ( void * ptr, size_t size ):

ptrパラメーターが指すメモリー・ブロックのサイズがsizeバイトに変更され、ブロックで使用可能なメモリーの量が拡大または縮小されます。この関数は、メモリ ブロックを新しい場所に移動する場合があり、その場合、新しい場所が返されます。

の場合、関数は とまったく同じように動作しptr、新しいバイト ブロックを割り当て、その先頭へのポインタを返します。NULLmallocsize

あなたの場合、ポインターは既に解放されていますが、まだ解放されていないNULLため、プログラムがこのメモリ ブロックを移動しようとすると、メモリが破損します。

これを解決するには、次のいずれかを実行する必要があります。

  • 削除しfree()ます。
  • mallocの代わりに使用しreallocます。
  • LineBufの後に NULL に設定しますfree()
于 2011-12-17T14:49:15.007 に答える
0

free(LineBuf)はメモリを解放していますが、後でreallocを呼び出すときにLineBufを再び使用しています。LineBufを解放した後、NULLに設定する必要があります。そうすると、reallocはmallocを実行し、再割り当ては行いません。ポインタを解放した後、ポインタをNULLに設定することは常に良い習慣であることに注意してください。これは、解放されたメモリへのポインタを使用しているかどうかを検出するのに役立ちます。

ところで、あなたのコードを見ると、あなたが何をしようとしているのかよくわかりません。やりたいことに応じて、LineBufまたはfgetsを取り除くことができます。また、すべてのiに対してstrlenを呼び出すことはあまりパフォーマンスが高くないため、temp [i]!='\0'を確認することをお勧めします。

于 2011-12-17T15:09:14.747 に答える