-2

以下のコードは、fwriteを使用してデータストリームをファイルに保存しようとします。mallocを使用した最初の例は機能しますが、2番目の例ではデータストリームが%70破損しています。2番目の例が破損している理由と、それを修正する方法を誰かに説明してもらえますか?

short int fwBuffer[1000000];
// short int *fwBuffer[1000000];
unsigned long fwSize[1000000];

// Not Working *********

if (dataFlow) {
       size =  sizeof(short int)*length*inchannels;
        short int tmpbuffer[length*inchannels];
        int count = 0;
        for (count = 0; count < length*inchannels; count++)
        {
            tmpbuffer[count] = (short int) (inbuffer[count]);
        }

        memcpy(&fwBuffer[saveBufferCount], tmpbuffer, sizeof(tmpbuffer));
        fwSize[saveBufferCount] = size;

        saveBufferCount++;
        totalSize += size;
    }
// Working ***********

if (dataFlow) { 
    size =  sizeof(short int)*length*inchannels;
    short int *tmpbuffer = (short int*)malloc(size);

    int count = 0;
    for (count = 0; count < length*inchannels; count++)
    {
        tmpbuffer[count] = (short int) (inbuffer[count]); 
    }

    fwBuffer[saveBufferCount] = tmpbuffer;
    fwSize[saveBufferCount] = size;

    saveBufferCount++;
    totalSize += size;
}


// Write to file ***********

    for (int i = 0; i < saveBufferCount; i++) {
        if (isRecording && outFile != NULL) { 
  //        fwrite(fwBuffer[i], 1, fwSize[i],outFile);
            fwrite(&fwBuffer[i], 1, fwSize[i],outFile);
            if (fwBuffer[i] != NULL) {
  //           free(fwBuffer[i]);
            }
            fwBuffer[i] = NULL;
        }
    }       
4

2 に答える 2

1

これはクラッシュする可能性が非常に高いです

short int tmpbuffer[(short int)(size)];

最初のサイズは大きすぎる可能性がありますが、それを切り捨てて、そのサイズの結果を得るのは、おそらくあなたが望むものではありません。

編集:単一のキャストなしでコード全体を書いてみてください。そうして初めて、コンパイラは何か問題があるかどうかを通知する機会があります。

于 2012-06-07T15:23:53.500 に答える
1

sizeあなたはあなたを初期化します

size = sizeof(short int) * length * inchannels;

次に、サイズの配列を宣言します

short int tmpbuffer[size];

これはすでに非常に疑わしいです。サイズに含めて、そのサイズの要素sizeof(short int)の配列を宣言したのはなぜですか?short intこの場合の配列のバイトサイズは

sizeof(short int) * sizeof(short int) * length * inchannels

つまり、sizeof(short int)は2回因数分解されます。

後でlength * inchannels、上記の理由により、配列全体ではなく、配列の要素のみを初期化します。しかし、memcpyそれに続くものはまだアレイ全体をコピーします

memcpy(&fwBuffer[saveBufferCount], &tmpbuffer, sizeof (tmpbuffer));

(コピーされたデータのテール部分はガベージです)。sizeof(short int)意図したよりも何倍も多くのデータをコピーしているのではないかと思います。受信者のメモリがオーバーフローし、破損します。

-edメモリサイズは-sではなくバイトで指定されるため、に基づくバージョンでmallocはこの問題は発生しません。mallocshort int

コードの上位バージョンでの動作をシミュレートする場合は、要素ではなく要素の配列としてmalloc宣言する必要があります。tmpbuffercharshort int

于 2012-06-07T15:31:15.703 に答える