0

ファイルから数バイトを読み取る次の抽象化されたコードを考えてみましょう。

typedef struct A{
int size;
char * dataArray;
}A

A load(char* filename, int inSize)
{
    A newA;
    newA.size = inSize;
    FILE *filePtr;
    filePtr = fopen(filename,"rb");

    char buff[1];
    int i = 0;

    newA.dataArray = ( char*)malloc(sizeof(char) * newA.size);
    for (i = 0; i < newA.size; i++)
    {
        fread(buff, sizeof(char), 1, filePtr);
        newA.dataArray[i] = buff[0];
    }

    char* copyOfDataArray = (char*)malloc(sizeof(char) * newA.size);

    for (i = 0; i < newA.size; i++)
    {
        fread(buff, sizeof(char), 1, filePtr);
        copyOfDataArray[i] = newA.dataArray[i];
    }

    newA.dataArray = copyOfDataArray;
    return newA
}

void Initialize()
{
    A first = load("file1", 100);
    A second = load("file2", 20);
}

関数 load の両方の呼び出しで、期待される結果が返されます (データ配列のバイト数はファイルと同じです)。変数 first と second は二度と使用されません。

ただし、数百行のコードの後、プログラムは常に次のようにクラッシュします。

*malloc.c:2451: sYSMALLOC: Assertion '(old_top == (..... failed.*

クラッシュは常に同じコード行で発生しますが、その行は最初、2 番目の変数、さらには構造体 A とは何の関係もありません。

私の質問は次のとおりです。「最初」と「2番目」のインスタンス化とロードの方法は間違っていますか? ロード関数が終了してから長い間プログラムをクラッシュさせる、ある種のメモリリーク/メモリオーバーフローを引き起こす可能性はありますか?

ボーナス:「file1」のみをロードするとクラッシュは発生しませんが、「file1」と「file2」の両方をロードするとすぐにクラッシュが再発します。

長い質問で申し訳ありません。

4

2 に答える 2

1

そこにメモリリークがあります。新しいメモリを割り当てる前に、newA.dataArray で以前に割り当てられたメモリを解放する必要があります。

Joachim が述べたように、読み取り操作には非常に時間がかかり、オーバーヘッドを最小限に抑えるためにデータをブロック単位で読み取る必要があります。

さらに、ファイル記述子を閉じる必要があります。そうしないと、すぐに使い果たされてしまいます。

于 2014-09-05T12:53:43.533 に答える