1

以下はLibaiffライブラリからのものです。次のエラーが完全にランダムに発生します(つまり、プログラムが問題なく動作することもあれば、このエラーでスタックして、常にこの関数内の同じポイントで中断することもあります)。(1949,0x7fff7b82d310) malloc: * オブジェクト 0xd00000000b400 のエラー: 解放されるポインターが割り当てられませんでした *デバッグするために malloc_error_break にブレークポイントを設定します

私の質問は、r->buffer2すでに解放されている場合、コントロールがステートメントif (r->buffer2)を通過してブロックに入って実行を試みることは可能free(r->buffer2)ですか? 言い換えれば、r->buffer2解放された場合、解放が再び起ころうとするのを防ぐべきではありませんif (r->buffer2)か?

static void AIFF_ReadClose(AIFF_Ref r)
{
    if (r->buffer)
        free(r->buffer);
    if (r->buffer2)
        free(r->buffer2);  // THIS IS WHERE THE BREAK OCCURS EVERYTIME
    Unprepare(r);
    fclose(r->fd);
    free(r);
    return;
}

編集:

の定義は次のとおりですAIFF_Ref

struct s_AIFF_Ref {
    FILE* fd;
    int flags;
    int stat; /* status */
    int segmentSize;
    int bitsPerSample;
    int nMarkers;
    int nChannels;
    double samplingRate;
    uint64_t nSamples;
    int markerPos;
    uint64_t len;
    uint64_t soundLen;
    uint64_t pos;
    uint64_t sampleBytes;
    uint64_t commonOffSet;
    uint64_t soundOffSet;
    uint64_t markerOffSet;
    IFFType format;
    IFFType audioFormat;
    void* decoder;
    void* pdata;
    void* buffer;
    size_t buflen;
    void* buffer2;
    size_t buflen2;
    int tics;
};

typedef struct s_AIFF_Ref* AIFF_Ref;

なぜこの奇妙な動作が起こっているのか、どうすれば解決できるのか、誰か提案できますか? ありがとう。

4

5 に答える 5

2

ドキュメントから、

free 関数は、calloc、malloc、または realloc の呼び出しによって以前に割り当てられたメモリ ブロック (memblock) の割り当てを解除します。(最初のフリーケースを想定)

memblock が NULL の場合、ポインターは無視され、free はすぐに戻ります。(ポインタをNULLに設定したことがないため、ここに来たことはありません)

無効なポインター (calloc、malloc、または realloc によって割り当てられていないメモリ ブロックへのポインター) を解放しようとすると、後続の割り当て要求に影響を与え、エラーが発生する可能性があります。(2番目のフリーケースを想定)

if (r->buffer2) { free(r->buffer2); r->buffer2 = NULL ; // ポインターを常に NULL に設定します。 // メモリを再び「解放」する可能性が疑わしい場合は、
// 別の場所にします。}

if (r->buffer2)
{ 
 free(r->buffer2);
 r->buffer2 = NULL ;
}

これは、メモリを解放するfreeと、メモリが'd されることは保証されますが、ポインター変数に書き込まれた値freeが削除または '化されることは保証されないためです。NULLしたがって、あなたのケースif( r->buffer2 )が当てはまるTRUEため、フローはifブロックに入ります。

于 2014-03-18T04:30:07.157 に答える
0

質問への回答と、役立つ可能性のある追加情報を見つけてください。

r->buffer2 が解放された場合、if (r->buffer2) は解放が再び起ころうとするのを防ぐべきではありませんか?

メモリがすでに解放されているかどうかという情報を知る方法はありません。誰かが指摘したように、「null」でポインターをチェックすると、いくつかの健全性チェックが行われ、通常はそのように行います。ただし、これは、ロジックがメモリを解放した後にポインターを「null」に設定した場合にのみ機能します。そうしないと、「null」チェックが機能せず、ポインターが「null」に割り当てられていないため、現在のコードで「free」が実行されます。 ' メモリを解放している間。

アドレスを調べると、「buffer2」にはガベージ値があり、プログラムを実行しているときはいつでも別のアドレス値を取得する必要があることがわかりました。これは、「AIFF_Ref」オブジェクトが適切に初期化されていない可能性があり、まだガベージ値を保持しているシナリオで発生する可能性があります。それを行う1つの方法は、設定することです

memset((void*)r, 0, sizeof(struct s_AIFF_Ref));

これにより、すべてがデフォルト値で初期化されます。これにより、yout 'buffer2' 変数にガベージ値が割り当てられる可能性を回避できます。

これらはいくつかのライブラリのロジックであると述べたので、動的ツールを使用してエラーをすばやく理解し、問題が発生している時点で使用することをお勧めします。あなたの説明から、プログラムに何らかのメモリがある可能性もあります。腐敗。この問題についても、以前の投稿が役立つと思います。プログラムが Windows 固有のものである場合は、次のリンクが表示されます。

https://stackoverflow.com/a/22074401/2724703

プログラムが Gnu/Linux 固有のものである場合は、次のリンクが表示されます。

https://stackoverflow.com/a/22085874/2724703

于 2014-03-18T04:05:55.713 に答える