1

stdin からデータを読み取るコードを作成しようとしています。

size_t bufSize = 1024;
unsigned char *msg = NULL;
size_t msgBytes = 0;
size_t inputMsgBufCount = 0;
unsigned char inputBuffer[bufSize];
size_t bytesRead = 0;
unsigned char *tmp = NULL;

if ((msg = (unsigned char *)malloc(sizeof(unsigned char) * bufSize)) == NULL)
    exit(EXIT_FAILURE);
bytesRead = fread(msg, sizeof(unsigned char) * bufSize, 1, stdin);
inputMsgBufCount++;

while (bytesRead) {
    printf("iteration: %lu\n", inputMsgBufCount);
    if ( (tmp = (unsigned char *)realloc(msg, (inputMsgBufCount * bufSize) + bufSize)) != NULL ) {
         printf("reallocated\n");
        msg = tmp;
        inputMsgBufCount++;
    }
    else {
        printf("Ran out of memory\n");
        free(msg);
    }
    bytesRead = fread(inputBuffer, sizeof(unsigned char) * bufSize, 1, stdin);
    memmove((msg + (inputMsgBufCount * bufSize)), inputBuffer, bufSize);
}

free(msg);

msgBytes = (inputMsgBufCount * bufSize);

gettimeofday(&end, NULL);
printf("%10.6lf [MB/s]\n", (msgBytes / (1<<20)) / ( (end.tv_sec - start.tv_sec) + (end.tv_usec - start.tv_usec) * 1.0e-6f ));

しかし、次のように実行した後: ~# dd if=/dev/zero bs=1024 count=8 | ./test このエラーがあります:

反復: 1
再割り当て
反復: 2
再割り当て
反復: 3
再割り当て
反復: 4
再割り当て
反復: 5
再割り当て
反復: 6
再割り当て
反復: 7
test(11450) malloc: *** オブジェクト 0x100804008 のエラー: 解放されたオブジェクトのチェックサムが正しくありません - オブジェクトは解放後に変更された可能性があります。
*** デバッグするために malloc_error_break にブレークポイントを設定します
トラップの中止

誰でも私を助けてください。

4

1 に答える 1

3

inputMsgBufCountメッセージバッファにデータをコピーしたにインクリメントされるはずです。最初の読み取りでそれを正しく行いますが、それ以外の場合は、再割り当ての直後にインクリメントします。その値に従うと、ループに入ると 1 になります。に再割り当てし2*bufSize、 をインクリメントinputMsgBufCountして 2 にします。次に、データを読み取り、 にコピーしmsg+2*bufSizeます。これにより、バッファが破損しています。にコピーする必要がありますmsg+bufSize。データをコピーするまで、変数のインクリメントを遅らせるだけです。

別の注意として、memcpy()データのコピーに安全に使用できます。msg重なり合うことはありinputBufferません。実際には、おそらく完全に取り除き、正しいオフセットでinputBuffer直接読み取る必要があります。msg

于 2011-04-12T23:57:20.673 に答える