Objective-Cでアプリケーションをプログラミングしていますが、このエラーが発生します。
MyApp(2121,0xb0185000)malloc:***オブジェクト0x1068310のエラー:ダブルフリー
*** malloc_error_breakにブレークポイントを設定してデバッグします
NSAutoreleasePoolをリリースすると発生しますが、2回リリースしているオブジェクトがわかりません。
彼のブレークポイントを設定するにはどうすればよいですか?
この「オブジェクト0x1068310」が何であるかを知る方法はありますか?
デバッガーを中断すると、オブジェクトが何であるかがわかります。呼び出しスタックを調べるだけで、どこで解放できるかがわかります。これにより、どのオブジェクトであるかがわかります。
ブレークポイントを設定する最も簡単な方法は次のとおりです。
- 実行->表示->ブレークポイント(ALT-Command-B)
- リストの一番下までスクロールして、シンボル
malloc_error_break
を追加します
オブジェクトが「二重解放」されている場合、最も一般的な原因は、自動解放されたオブジェクトを(不必要に)解放していることであり、後でそれを含む自動解放プールが空になると自動解放されます。
余分なリリースを追跡する最良の方法は、Xcodeで影響を受ける実行可能ファイルに対してNSZombieEnabled環境変数を使用することであることがわかりました。使用方法の概要については、 このCocoaDev wikiページ をご覧ください。 (このページに加えて、AppleはXcodeでコードをデバッグするためのいくつかの信じられないほど不明瞭で有用なヒントを文書化しました。そのいくつかは私のベーコンを数回以上保存しました。 このテクニカルノート developer.Apple.comで—リンクはCocoaのFoundationフレームワークのセクションにジャンプします)。
編集:多くの場合、Xcodeデバッガー内で問題のオブジェクトを追跡できますが、多くの場合、Instrumentsを使用して支援する方がはるかに簡単です。 XcodeからRun→Performance Toolで開始→Object Allocationsを選択すると、問題のオブジェクトを作成された場所までトレースできるようになります。 (これは、上記のようにゾンビを有効にしている場合に最適に機能します。)注:Snow Leopardは、[実行]メニューからアクセスできるインストゥルメントにゾンビツールを追加します。同様に。 29ドルだけの価値があるかもしれません! ;-)
関連SOここに質問 もあります。
クイン・テイラーの答えに加えて、私の経験を加えたいだけです。
私のアプリの1つでは、データを解析してコアデータオブジェクトに保存し、後でこれらのオブジェクトをビューに表示する必要があります。実際、アプリは正常に動作し、何度も前後に移動するストレステストを試行し、できるだけ速く複数のビューを開こうとするまで、まったくクラッシュしません。上記のメッセージでアプリがクラッシュします。
私はクインが彼の答えで示唆したすべての方法を試しましたが、それでも正確な原因がどこにあるかを見つけることができませんでした。
NSZombieEnabled = YESとNSStackLogging = YESを設定し、シェルmalloc_historyコマンドを実行して理由を調べましたが、それでも運はありません。常に、データをコアデータオブジェクトに保存する場所を示しています。実際、そこに過剰にリリースされたオブジェクトを何千回もチェックしていますが、奇妙なことはありません。
さまざまなツール(割り当て、リークなど)を使用してInstrumentsを実行しても、まだ役に立ちませんでした。 Guard Mallocを有効にしても、まだ何も得られません。
最終的な救助:私はオブジェクトがCore Dataから取得されたビューに戻り、これらすべてのオブジェクトに保持メッセージを送信して、これらの変更に注意しました。問題を解決しました!!!
だから、私は1つを保持することに失敗したことがわかりました、それがまさに原因です。私の経験を共有したいので、アプリの別の救助があります。
Cmd + Shift + Rを押して、デバッガコンソールを開きます。そこに、タイプ
break malloc_error_break
malloc_error_break
関数の先頭にブレークポイントを設定します。
アドレス0x1068310にあるオブジェクトを調べるには、デバッガコンソールに次のように入力します。
print-object 0x1068310
もちろん、オブジェクトがまだ存在している間にこれを行う必要があります。これを行うまでにオブジェクトがすでに解放されている場合、これは機能しません。
私にとってこの問題は
(gdb) call (void)_CFAutoreleasePoolPrintPools()
クラッシュ直後。スタックの一番上のアドレスは、犯人のアドレスでした。 retain
と出来上がりを投入しました。
ログメッセージで指定されたアドレスは、どこにも行きませんでした。さまざまなInstrumetsのいずれにも現れませんでした。明らかに、すでに解放された内部データへのポインタ。
これをXcode 4に関連させるための更新...
Xcode 4ユーザーガイド から:
シンボリックブレークポイントを追加するには。 。 。
- ブレークポイントナビゲーターの左下隅にある[追加]ボタンをクリックします。
- [シンボリックブレークポイントの追加]を選択します。
- [シンボル]フィールドにシンボル名を入力します。
- 完了をクリックします。
これは、Xcodeの[ブレークポイント]ウィンドウでmalloc_error_breakブレークポイントがどのように見えるかです。動作させるにはボックスをチェックする必要があります。
代替テキストhttp://www.martijnthe.nl/wp-content/uploads/2009/08/Afbeelding-1.png
クラスを確認し、deallocメソッドを確認します。 _[super dealloc].
これとまったく同じ問題があり、[self dealloc]
代わりに。ただ注意を払っていない。
Xcodeで、行番号の左をクリックしてブレークポイントを設定します。その後、「ビルドとデバッグ」を実行して起動できます。
メモリはiPhoneの商品であるため、作成するオブジェクトをautorelease
にしないことをお勧めします。 Apple release
を明示的に呼び出すことをお勧めします。
これらの種類のメモリとポインタの問題を一般的に見つけるには、 Valgrind のようなランタイムメモリエラーチェッカーに対してコードを実行します。これは、コードがクラッシュする原因を超えて、コードが間違っていることの多くを指摘できるはずです。
Valgrind OSXで動作可能 (「サポートされておらず、不完全でバグがある」と言います)、そして少しハッキングして誰かが動作するようになりました iPhone SDK実行可能ファイル 。
XCodeの一部であるInstrumentsを試すこともできます。それを実行するためのチュートリアルがあります こちら 。
malloc_error_break
は役に立たない...
このエラーを解決する最良の方法は、NSZombies
をオンにしてinstrumentsを実行することです。ゾンビにメッセージが送信されると、インストゥルメントがフラグを立て、コード行に直接戻ることができます。
Snow Leopardが必要でしたが、なんと命の恩人でしょう!