EXC_BAD_ACCESSシグナルを受信しました


290

アプリケーションをデバイスにデプロイすると、プログラムは数サイクル後に次のエラーで終了します。

Program received signal: "EXC_BAD_ACCESS".

プログラムはiPhoneシミュレーターで問題なく実行されます。また、命令を1つずつ実行する限り、デバッグして実行されます。もう一度走らせたらすぐにEXC_BAD_ACCESS信号を打ちます。

この特定のケースでは、それは偶然にも加速度計コードのエラーでした。シミュレーター内では実行されないため、エラーはスローされませんでした。ただし、デバイスに展開されると実行されます。

この質問に対する回答のほとんどは一般的なEXC_BAD_ACCESSエラーを扱っているため、恐ろしい不正アクセスエラーのキャッチオールとしてこれを開いたままにしておきます。

EXC_BAD_ACCESS通常、不正なメモリアクセスの結果としてスローされます。詳細については、以下の回答をご覧ください。

EXC_BAD_ACCESS以前に信号に遭遇したことがありますか?どのように対処しましたか?

回答:


196

あなたの説明から、私は最も可能性の高い説明はあなたがあなたのメモリ管理にいくつかのエラーを持っていることだと思います。あなたは数週間iPhone開発に取り組んできたと言いましたが、一般的にObjective Cの経験があるかどうかは違います。別の経歴を持っている場合、メモリ管理ルールを実際に内部化するまでに少し時間がかかることがあります。

割り当て関数(通常は静的allocメソッドですが、他にもいくつかあります)、またはコピーメソッドから取得したものはすべてメモリを所有し、完了時に解放する必要があります。

しかし、ファクトリーメソッド(例:)を含む他のほぼすべてから何かを取得した場合[NSString stringWithFormat]、自動解放参照があります。つまり、将来的に他のコードによって解放される可能性があるため、必要な場合に不可欠です。あなたがそれを保持する当面の機能を超えてそれを維持するため。そうしないと、エミュレーターのテスト中に、メモリの使用中にメモリが割り当てられたままになるか、解放されますが、偶然にも有効ですが、デバイスで実行すると、解放されて不良アクセスエラーとして表示される可能性が高くなります。

これらを追跡する最良の方法、そしてとにかく(明らかな問題がない場合でも)良いアイデアは、特にリークオプションを使用して、Instrumentsツールでアプリを実行することです。


2
アプリに不可欠ではない加速度計のサンプリングコードがあり、これを削除すると、不正なアクセスエラーが解消されました。これは、シミュレータに加速度計がないことを考えると理にかなっています。私は...このエラーの原因と前の週のために、そのまま、このコードが存在していること、それは奇妙な見つけるのですか
ヘクター・ラモス

私はObjective-Cを初めて使用するので、問題のほとんどはメモリ管理から発生するはずです。C ++での数年後、私は過去3年間または4年間ほとんどJavaを使用してきたので、メモリ管理に錆びてきました。ご回答有難うございます!
ヘクター・ラモス

4
問題ありません-修正してよかったです。メモリ管理を上手く実行するのは本当に難しいことではありません。ルールを学び、良い習慣を身につける必要があるだけです。
philsquared 2008年

私が持っていた問題は、私が作成した文字列(など)をリリースすることにあまりにも積極的であることだけにあるようです。何をいつリリースするかはまだ100%わかりませんが、Philの答えは確かに役に立ちました。
pluckyglen 2009年

私がそれを正しくフォローした場合、cmculloh、はい、それは正しいことでした。objectAtIndexからのオブジェクトリターンを所有していません。
philsquared 2009

101

EXC_BAD_ACCESSの主な原因は、解放されたオブジェクトにアクセスしようとしたことです。

これをトラブルシューティングする方法を見つけるには、このドキュメントを読んでください: DebuggingAutoReleasePool

「自動解放オブジェクトを解放する」とは思わなくても、これはあなたに適用されます。

この方法は非常にうまく機能します。ずっと使って大活躍!!

要約すると、CocoaのNSZombieデバッグクラスとコマンドラインの「malloc_history」ツールを使用して、コード内でアクセスされたリリース済みオブジェクトを正確に見つける方法を説明します。

サイドノート:

Instrumentsを実行してリークをチェックしても、EXC_BAD_ACCESSのトラブルシューティングには役立ちません。私はメモリリークがEXC_BAD_ACCESSとは何の関係もないと確信しています。リークの定義は、アクセスできなくなったオブジェクトであるため、呼び出すことはできません。

更新: リークのデバッグにInstrumentsを使用しています。Xcode 4.2から、[製品]-> [プロファイル]を選択し、Instrumentsが起動したら、[ゾンビ]を選択します。


18
その傍注は非常に重要です。リークによってEXC_BAD_ACCESSが発生することはありません(他の問題があります)。EXC_BAD_ACCESS
Lou Franco

4
Xcodeのそのゾンビツールは素晴らしいです!犯人は数時間ではなく3分で見つかりました。
Aram Kocharyan、2012年

1
上記のリンクの回答はありません。404 not foundエラーが表示されます。
Tejas 2017年

12

EXC_BAD_ACCESSシグナルは、無効なポインターをシステムコールに渡した結果です。今日、OS Xのテストプログラムで1つ取得しました。初期化されていない変数をに渡していましたpthread_join()。これは、以前のタイプミスが原因でした。

私はiPhoneの開発に精通していませんが、システムコールに渡すすべてのバッファーポインターを再確認する必要があります。コンパイラの警告レベルを完全に上げます(gccを使用する場合は、-Wallおよび-Wextraオプションを使用します)。シミュレータ/デバッガで可能な限り多くの診断を有効にします。


8

私の経験では、これは通常、不正なメモリアクセスが原因です。すべてのポインター、特にオブジェクトポインターをチェックして、それらが初期化されていることを確認します。MainWindow.xibファイルを使用している場合は、必要なすべての接続が正しく設定されていることを確認してください。

紙面での確認で問題が解決せず、シングルステップで問題が発生しない場合は、NSLog()ステートメントでエラーを見つけてください。コードを振りかけ、原因となっている行を特定するまで移動してください。エラー。次に、その行にブレークポイントを設定し、プログラムを実行します。ブレークポイントに到達したら、すべての変数とその中のオブジェクトを調べて、期待どおりに見えないものがないか確認します。特に、オブジェクトクラスが予期しないものである変数に注意します。変数にUIWindowが含まれているはずなのに、代わりにNSNotificationが含まれている場合、デバッガーが動作していないときに、同じ基本的なコードエラーが別の方法で現れている可能性があります。


7

数時間かけてEXC_BAD_ACCESSを追跡したところ、NSZombiesと他の環境変数が何も教えてくれないようでした。

私にとっては、フォーマット指定子を含むが、引数が渡されない愚かなNSLogステートメントでした。

NSLog(@"Some silly log message %@-%@");

によって修正

NSLog(@"Some silly log message %@-%@", someObj1, someObj2);

6

2010 WWDCビデオは、アップル開発者プログラムのすべての参加者が利用できます。すばらしいビデオがあります。「セッション311-インストゥルメントを使用した高度なメモリ分析」では、インストゥルメントでゾンビを使用し、他のメモリの問題をデバッグする例をいくつか紹介しています。

ログインページへのリンクについてはクリックしてくださいHERE


6

完全な答えではありませんが、これを受け取った特定の状況の1つは、自動解放を使用しようとしたために「死んだ」オブジェクトにアクセスしようとしたときです。

netObjectDefinedInMyHeader = [[[MyNetObject alloc] init] autorelease];

たとえば、私は実際にこれを「通知」するオブジェクトとして渡しました(リスナー、オブザーバー、好きなイディオムとして登録しました)が、通知が送信されるとすでに終了しており、EXC_BAD_ACCESSを取得します。変更し[[MyNetObject alloc] init]て後で適切にリリースすると、エラーが解決しました。

これが発生するもう1つの理由は、たとえば、オブジェクトを渡してそれを保存しようとした場合です。

myObjectDefinedInHeader = aParameterObjectPassedIn;

後でmyObjectDefinedInHeaderにアクセスしようとすると、問題が発生する可能性があります。使用:

myObjectDefinedInHeader = [aParameterObjectPassedIn retain];

あなたが必要とするものかもしれません。もちろん、これらは私が遭遇したことのほんの数例であり、他の理由もありますが、これらはとらえどころのないものになる可能性があるので、それらについて言及します。幸運を!


5

これが起こり得る別の状況を追加するだけです:

私はコードを持っていました:

NSMutableString *string;
[string   appendWithFormat:@"foo"];

明らかに、文字列にメモリを割り当てるのを忘れていました。

NSMutableString *string = [[NSMutableString alloc] init];
[string   appendWithFormat:@"foo"];

問題を修正します。


文字列がnilに初期化され、nilでメソッドを呼び出すnullオブジェクトパターンを使用しても何も実行されないため、これによってエラーが発生することはありません。
Liron Yahdav 2014年

5

EXC_BAD_ACCESS例外が発生する前にキャッチする別の方法は、XCode 4+の静的アナライザーです。

製品>分析(shift + cmd + B)で静的アナライザーを実行します。アナライザーによって生成されたメッセージをクリックすると、問題のあるオブジェクトの保持/解放のシーケンスを示す図がソースにオーバーレイされます。

ここに画像の説明を入力してください


5

objc_exception_throwにブレークポイントを設定すると便利です。そうすれば、EXC_BAD_ACCESSを取得したときにデバッガーが壊れます。

手順はここにありますDebuggingTechniques


4

「割り当ても保持もしなかった場合は、解放しない」という単純なルールを使用してください。


1
「...それをコピー...」でそのルールを拡張すると、大丈夫です。
ティル

4

EXC_BAD_ACCESSをデバッグする方法

上記のリンクを確認して、記載されているとおりに実行してください。

アプリケーションを実行し、失敗した後(「EXC_BAD_ACCESS」ではなく「Interrupted」と表示する必要があります...コンソールを確認します([実行]> [コンソール])...アクセスしようとしているオブジェクトを示すメッセージが表示されます。

-ベン


3

このエラーを解決するために、過去4時間、コードのデバッグとリファクタリングを行ってきました。上記の投稿で問題が発生しました。

前のプロパティ:startPoint = [[DataPoint alloc] init]; startPoint = [DataPointList objectAtIndex:0];
。。。x = startPoint.x-10; // EXC_BAD_ACCESS

後のプロパティ:startPoint = [[DataPoint alloc] init]; startPoint = [[DataPointList objectAtIndex:0]保存];

さようならEXC_BAD_ACCESS


私も同じような間違いをしました。クラッシュの原因となったインスタンスを再配置するのを忘れて、それを解明するのに何時間も費やしました。あなたの経験が私のことを知るきっかけになりました。ありがとう!
David.Chu.ca 2010

3

完了したら「ストリング」を解放してください。


3

init-Methodで自分自身を返すのを忘れました...;)


これは、実行時のEXC_BAD_ACCESSではなく、コンパイル時の警告/エラーである必要があります。
stigi 2014

3

これは優れたスレッドです。これが私の経験です。私はプロパティ宣言の保持/割り当てキーワードをめちゃくちゃにしました。私は言った:

@property (nonatomic, assign) IBOutlet UISegmentedControl *choicesControl;
@property (nonatomic, assign) IBOutlet UISwitch *africaSwitch;
@property (nonatomic, assign) IBOutlet UISwitch *asiaSwitch;

私が言っておくべきだった場所

@property (nonatomic, retain) IBOutlet UISegmentedControl *choicesControl;
@property (nonatomic, retain) IBOutlet UISwitch *africaSwitch;
@property (nonatomic, retain) IBOutlet UISwitch *asiaSwitch;

1
奇妙なことに、なぜIBOutletを保持する必要があるのでしょうか。管理は自動的に行われます。
jv42

3

大きな配列を含むCメソッドを実行しようとしたときにのみ、iPhoneでEXC_BAD_ACCESSが発生しました。シミュレータはコードを実行するのに十分なメモリを私に与えることができましたが、デバイスには与えられませんでした(配列は100万文字だったので、少し過剰でした!)。

EXC_BAD_ACCESSはメソッドのエントリポイントの直後に発生し、配列宣言の近くにないため、しばらく混乱していました。

おそらく、誰かが私の髪を引っ張る数時間から恩恵を受けるかもしれません。


3

から割り当てられていないポインタを取り出すのを忘れましたdealloc。UINavigationControllerのrootViewでexc_bad_accessを取得していましたが、ときどきしかありませんでした。viewDidAppear {}の途中でクラッシュしたため、問題はrootViewにあると思いました。それは私が悪いdealloc {}リリースでビューをポップした後にのみ起こりました、そしてそれだけでした!

"EXC_BAD_ACCESS" [プロセス330への切り替え]プログラムに使用できるメモリがありません:mallocを呼び出すのは安全ではありません

私がアロケートしようとしているところの問題だと思った...アロケートを解放しようとしているところではない、D'oh!


3

EXC_BAD_ACCESSの扱い方

EXC_BAD_ACCESSエラーがスローされると、xcodeがmain.mクラスにエラーを表示し、クラッシュが発生した場所に関する追加情報を提供しないと感じることがあります(ときどき)。

そのような場合は、Xcodeで例外ブレークポイントを設定して、例外がキャッチされたときにブレークポイントが配置され、その行でクラッシュが発生したことをユーザーに直接知らせることができます。

ここに画像の説明を入力してください



2

私はこの問題を抱えていました。私にとっての理由は、後で別の場所から読み取ろうとするCoreData管理対象オブジェクトを削除することでした。


2

このエラーを解決するために、過去4時間、コードのデバッグとリファクタリングを行ってきました。上記の投稿で問題が発生しました。

前のプロパティ:

startPoint = [[DataPoint alloc] init] ;
startPoint= [DataPointList objectAtIndex: 0];
x = startPoint.x - 10; // EXC_BAD_ACCESS

後のプロパティ:

startPoint = [[DataPoint alloc] init] ;
startPoint = [[DataPointList objectAtIndex: 0] retain];

さようなら EXC_BAD_ACCESS

回答ありがとうございます。私は一日中この問題に取り組んできました。あなたは素晴らしいです!


4
すぐにstartPointを上書きしていませんか?最初の行はまったく必要ないと思います。
toxaq

2
すぐに別の変数で上書きする場合は、変数を割り当てて初期化する必要はまったくありません。最初の割り当てでオブジェクトをリークしているだけです。
dreamlax

2

追加するだけ

Lynda.comには、素晴らしいDVDと呼ばれています。

iPhone SDKエッセンシャルトレーニング

第6章、レッスン3では、EXEC_BAD_ACCESSとゾンビの操作について説明します。

エラーコードだけでなく、リリースされたオブジェクトの詳細情報を取得するためにZombiesをどのように使用できるかを理解できたのは素晴らしいことでした。


2

エラーが何であるかを確認するには

NSZombieEnabledを使用します。

アプリケーションでNSZombieEnabled機能をアクティブにするには:

「プロジェクト」>「アクティブな実行可能ファイルを編集」を選択して、実行可能な情報ウィンドウを開きます。引数をクリックします。「環境に設定する変数」の追加(+)ボタンをクリックします。「名前」列にNSZombieEnabledと入力し、「値」列にYESと入力します。NSZombieEnabledエントリのチェックマークが選択されていることを確認します。

iPhoneSDKでこの答えを見つけました


2

私はこれが少し前に尋ねられたことに気づきましたが、このスレッドを読んだ後、私はXCode 4.2のソリューションを見つけました:製品->スキームの編集->診断タブ->ゾンビオブジェクトを有効化

割り当て解除されたオブジェクトに送信されているメッセージを見つけるのに役立ちました。


2

無限再帰がある場合、このエラーも発生する可能性があると思います。これは私の場合でした。


1

さらに別の可能性:キュー内のブロックを使用すると、この時点で既に割り当て解除されている別のキュー内のオブジェクトにアクセスしようとすることが簡単に起こります。通常、GUIに何かを送信しようとした場合。例外ブレークポイントが奇妙な場所に設定されている場合は、これが原因である可能性があります。


1

私が使用していなかったので、私はそれを得た[self performSegueWithIdentifier:sender:]-(void) prepareForSegue:(UIstoryboardSegue *)


1

忘れてはいけない@治療、文字列を作成するときにシンボルをC-stringsとしてNSStringsの意志原因EXC_BAD_ACCESS

これを使って:

@"Some String"

これよりも:

"Some String"

PS-通常、array大量のレコードを含むコンテンツにデータを入力する場合。


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.