2012-01-20 14 views
0

これは安価なハックですが、私が取り組んでいるCライブラリの割り当て方法を変更しようとしています。なんらかの理由でGlobalLockを使用していました。これはおそらく複数のDLLであったからです。私はALLOCにそれを変更しました:Cライブラリの更新中にヒープの破損が発生する

HANDLE BmiDibAlloc(size_t uBytes) 
{ 
    HANDLE alloc = malloc(uBytes + sizeof (size_t)); 

    if (alloc != NULL) 
    { 
     memcpy_s(alloc, sizeof (alloc), &uBytes, sizeof (size_t)); 
    } 

    return BmiDibAttach(alloc); //just tracks the number of memory allocs for logging 
} 

BOOL BmiDibFree(HANDLE hdib) 
{ 
    if (!hdib) { 
     return TRUE; 
    } 
    free(hdib); 
    // Forget this handle: 
    return BmiDibDetach(hdib); 
} 

割り当てられた後にビットマップが細かい書くとき、私は...最初のsizeof(size_tの)バイトの割り当てのサイズに私はタックもう

をGlobalSizeを使用することはできませんので、最初の方法で - しかし、私がフリーになると、ヒープの破損がスローされます。これらの呼び出しの間のどこかにある可能性があります。

+2

コードは正常に見えますが、おそらく問題はコードの残りの部分です。私が見ている唯一の間違いは 'sizeof(alloc)'が間違っていることです、 'sizeof(size_t)'でなければなりません(ただし、すべてのWindowsプラットフォーム 'sizeof(HANDLE)' == 'sizeof == 'sizeof(size_t)')。 –

+0

@MatteoItaliaなぜあなたは私がこれをする必要があるのか​​分かりますか?ライブラリの特定の部分は、以前は割り当てにGlobalSize()を使用していました。多分私はそれがvoid *ではなかったのでsizeof(* alloc)で置き換えることができました。 –

+0

サイズを前に付けると、このメモリを使用するすべてのものがそれに混乱していないことを確認しますか?たとえば、メモリブロックが実際にuBytes + sizeof(size_t)であることを考慮してください。サイズを変更しますか? – nos

答えて

2

ブロックを割り当てるときには、もう少し領域を割り当て、ブロックの先頭にヘッダーを格納してから、ブロック内のオフセット(ブロックの先頭ではない)へのポインタを返します。たとえば、 "return alloc + sizeof(MY_HEADER)"とします。

ブロックを解放するときは、その逆を行う必要があります。

BOOL BmiDibFree(HANDLE callerPointer) 
{ 
    actualPointer = callerPointer - sizeof(MY_HEADER); 
    free(actualPointer); 

注1:たとえばパフォーマンスを得るために、あなたは「はsizeof(MY_HEADER)は」「のmalloc()」が提供する最小アラインメントの倍数であることを確認する必要があります。したがって、発信者にとって誤整列の問題が発生することはありません。

注2:ブロックの実際の開始点とブロックの実際の端に「カナリアス」(マジックナンバー)を追加し、ヒープの破損を検出する機会を増やすためにこれらをチェックすることができます。私はこれを行い、 "heap was corrupted"フラグをセットし、malloc/free/reallocの前にこのフラグをテストします(もしヒープが壊れていれば、後続の操作はすぐに失敗してしまいます)。

注3:条件付きコンパイル(例:#ifdef DEBUGGING)を使用して、ラッパーのさまざまな機能を有効または無効にすることができます。私はこれもやっています - 余分なチェック(カナリアス)を可能にするものと、統計の収集/報告(割り当てられたブロックの総数、いつでも割り当てられるブロックの最大数、割り当てられたバイトの総数、任意の時間に割り当てられたバイト数)。

0

Q:実際に "sizeof(size_t)"を意味しますか?これは通常4バイトです。 "sizeof(alloc)"と同じです。おそらくちょうど "4"でしょう。

+0

sizeof(size_t)は、割り当てのサイズを格納するために余分な4バイトを割り当てたいと考えています。 sizeof(alloc)は私が思っていなかったものでも、allocの中の(elements?)の数でなければなりません...しかし、allocがポインタの大きさになるvoid *(HANDLE)のように見えますか? (私の32ビットOSで4バイトも、破損ではなく、技術的には正しくない) –

関連する問題