0

コードのこの部分でメモリを解放すると... :free(): 次のサイズが無効です (高速) というエラーが表示されます

int insertRecord(char *record,int recordSize,long dataPageNumber)
{
datapage *dataPage=(datapage *)malloc(sizeof(datapage));
readPage(dataPage,dataPageNumber);

slotentry slot;

//for checking and freeslotnumber storage
int freeSlotNumber=-1;
int negativeFlag=0;
int freeFlag=0;

if(recordSize+sizeof(slotentry)<=dataPage->cfs)
{
    slot.slotsize = recordSize;
    slot.slotaddress = dataPage->cfsptr;
    dataPage->cfs -= (recordSize+sizeof(slotentry));
    dataPage->cfsptr += recordSize;
    dataPage->slotcount++;

    memcpy(&dataPage->data[slot.slotaddress],record,recordSize);

    free(dataPage);
    return 1;
}

free(dataPage) を実行した後、上記のエラーが発生します...

typedef struct
{
   int pagenumber;
   int priority;
   long dirPageNo;
   long cfs;
   int cfsptr;
   int slotcount;
   char data[1];
} datapage;

typedef struct
{
   int slotaddress;
   int slotsize;
} slotentry;

memcpy の前に free(dataPage) を保持していましたが、memcpy の後は正常に動作していませんが、memcpy の後は動作しません..エラーが表示されます....

4

4 に答える 4

5

dataPage->dataエントリの場合、境界の外側に書き込むために、おそらくこれを取得しています。slot.slotaddress==0この構造体エントリの長さは 1 バイトなので、とでない限りrecordSize==1datapage struct. このメモリの破損がおそらくfreeエラーの原因です。

このタイプのエラーを追跡するには、次の方法でプログラムを実行することをお勧めしますvalgrind

valgrind progname args

この場合、「無効な書き込み」に関するメッセージが表示される可能性があります。これは、配列の境界外に書き込みを行っていることを示しています。

于 2012-11-05T20:01:21.747 に答える
3

data[]ほとんどの場合、1 つの要素に対して十分なスペースしかないメンバーに書き込むときに、割り当てた構造体の末尾を超えて書き込みを行っていることはほぼ確実です。(0 より大きいインデックスは、割り当てられたメモリを超えて書き込み、割り当てられたブロックのメタデータを上書きする可能性があります。)

また、stackoverflow に関するヘルプが必要な場合は、与えられた回答のいくつかを受け入れ始めることを強くお勧めします。

于 2012-11-05T19:59:40.597 に答える
2

私はあなたの memcpy() 行を見ています: memcpy(&dataPage->data[slot.slotaddress],record,recordSize);

その関数の使用法は次のとおりです。
void *memcpy(void *dest, const void *src, size_t n);

最初の引数は宛先です。&dataPage->data[slot.slotaddress] これは、割り当てた構造のセクションから始まるデータを保存するように要求していることを示しているdataPage->dataため、基本的にデータを上書きして、それを過ぎてララランドに移動します。

于 2012-11-05T20:06:11.023 に答える
2

あなたのバグは、このコード フラグメントの外にある可能性があります。gcc -Wall -gすべてのプログラムを(Linux 上で) でコンパイルし、警告が表示されなくなるまでコードを改善し、gdbおよびvalgrindを使用してプログラムをデバッグすることを強くお勧めします。

他のシステムを使用している場合は、コンパイル中にすべての警告とデバッグ情報を有効にし、メモリ リーク検出器を使用してみてください。

于 2012-11-05T19:59:43.233 に答える