1

コードにリンクされたリストがいくつかあります。各連結リストは、関数のローカル変数である C コードの大きな構造の一部です。このコードは、別の関数を使用してリストにデータを入力し、他の操作を実行してから、3 番目の関数を呼び出してリストを出力および削除します。最初のノードを削除する必要はありません。

問題: 関数はすべてのデータを正しく出力するため、ダングリング ポインターなどはありません。しかし、メモリを解放しようとすると、ヒープ破損エラーが発生します。このエラーをスローするコードのサンプルは次のとおりです。

flag = 0;

while( stpBS_current != NULL && stpFlags_current != NULL ){
// Linked list printing code is removed for clarity
    if( flag == 1 ){
        stpPrev = stpBS_current;
        stpFlags_prev = stpFlags_current;

        stpBS_current = (struct BasicService *)stpBS_current->pNext;
        stpFlags_current = (struct BasicService_Flags *)stpFlags_current->pNext;

        free( stpPrev );
        free( stpFlags_prev );
    }
    else
    {
        stpBS_current = (struct BasicService *)stpBS_current->pNext;
        stpFlags_current = (struct BasicService_Flags *)stpFlags_current->pNext;

        flag = 1;
    }
}

stpPrevおよびstpFlags_prevはローカル変数でstpBS_currentありstpFlags_current、print/delete 関数で引数として渡されます。元の連結リストに があるため、キャストが実行されますvoid *。同じ関数が保存されているすべてのデータを正しく出力し、このメモリは他の場所で解放されていないため、ポインターが正しいと確信しています。

私はここで完全に途方に暮れています。Google のすべてはバッファ オーバーフローに関するものですが、そうではないと確信しています。MS Visual C++ 2010 を使用していますが、表示されるエラーは次のとおりです。

Windows が ZTE Parser [24.04.2012].exe でブレークポイントをトリガーしました。

これは、ヒープの破損が原因である可能性があります。これは、ZTE Parser [24.04.2012].exe または読み込まれた DLL のバグを示しています。

これは、ZTE Parser [24.04.2012].exe にフォーカスがあるときにユーザーが F12 を押したことが原因である可能性もあります。

もちろん F12 は押していないので問題ありません。最初のエラーを無視してコードの実行を続行すると、同じ呼び出しからfree()返される前にいくつかのアサーション エラーが発生し、最終的には次のようになります。

MS VS 2010 ヒープ破損のスナップショット

void ポインターが原因ですか? しかし、結局のところ、malloc() と free() は void ポインターを使用するため、IMO ではこれは問題になりません。ヒープはグローバル メモリであるため、異なる関数での割り当てと割り当て解除は問題にならないはずです。

メモリを割り当てるコードは簡単です (2 つのリンクされたリスト)。わかりやすくするために、ヘッド ノードの初期化コードを削除しました。

stpBSC_current->pNext   =   malloc( sizeof(struct BasicServiceCode) );
stpFlags_current->pNext =   calloc( 1, sizeof(struct BasicServiceCode_Flags) );

if( stpBSC_current->pNext == NULL || stpFlags_current->pNext == NULL )
    exit( 1 );
else
{
    stpBSC_current      =   (struct BasicServiceCode *)stpBSC_current->pNext;
    stpFlags_current    =   (struct BasicServiceCode_Flags *)stpFlags_current->pNext;
}

メモリ割り当てまたはリンク リスト管理にループ ホールがあった場合、リストの印刷中にエラーが発生するか、少なくともデータの一部がゴミとして出てくるはずですが、完全に機能します。メモリを解放しようとすると、エラーが発生します。どんな助けやアイデアも高く評価されます。前もって感謝します。

4

3 に答える 3

1

フラグの状態が正しくないことが判明しました(一部の印刷コードは質問に表示されていません)。

原因:free()、を使用して割り当てられていないヘッド ノードを解放しようとしましたmalloc()。それは静的に割り当てられた変数でした。したがって、これは技術的には最初のエラーが示唆したようなヒープ破損ではありませんでしたが、指定されたアサーション失敗エラーは、もちろんスタック上のヒープ バッファの開始前にfree()あるメモリを解放しようとしていました。これがエラーの原因でした。

@everyone 助けと提案をありがとう。

于 2012-10-30T08:09:29.057 に答える
0

データを印刷できるからといって、ヒープが破損していないわけではありません。メモリを解放すると、メモリが再度割り当てられて上書きされるまで、データはそこに残ります。したがって、リンクされたリストには、解放されたメモリへのポインターが含まれている可能性があります。引き続きそれを読み取ることはできますが、後で問題が発生します。

于 2012-10-25T15:11:18.627 に答える
0

これは、ほぼ確実にバッファ オーバーフローが原因です。これにより、割り当てたメモリ ブロックの直前または直後に格納されているヒープ制御情報がコードによって上書きされます。このようなエラーは、メモリを解放しようとするまで検出されない場合があります。

考慮事項:

データを解析している場合 (プログラムの名前が示すように)、解析された入力をコピーするバッファーが十分な大きさであると確信していますか?

構造体 BasicServiceCode および BasicServiceCode_Flags には C スタイルの文字列が含まれていますか? その場合、バッファ オーバーフローが発生している可能性があります。null ターミネータには特に注意してください。

于 2012-10-27T08:17:41.507 に答える