EXC_BAD_ACCESS signal received

Viewed 275930

When deploying the application to the device, the program will quit after a few cycles with the following error:

Program received signal: "EXC_BAD_ACCESS".

The program runs without any issue on the iPhone simulator, it will also debug and run as long as I step through the instructions one at a time. As soon as I let it run again, I will hit the EXC_BAD_ACCESS signal.

In this particular case, it happened to be an error in the accelerometer code. It would not execute within the simulator, which is why it did not throw any errors. However, it would execute once deployed to the device.

Most of the answers to this question deal with the general EXC_BAD_ACCESS error, so I will leave this open as a catch-all for the dreaded Bad Access error.

EXC_BAD_ACCESS is typically thrown as the result of an illegal memory access. You can find more information in the answers below.

Have you encountered the EXC_BAD_ACCESS signal before, and how did you deal with it?

36 Answers

From your description I suspect the most likely explanation is that you have some error in your memory management. You said you've been working on iPhone development for a few weeks, but not whether you are experienced with Objective C in general. If you've come from another background it can take a little while before you really internalise the memory management rules - unless you make a big point of it.

Remember, anything you get from an allocation function (usually the static alloc method, but there are a few others), or a copy method, you own the memory too and must release it when you are done.

But if you get something back from just about anything else including factory methods (e.g. [NSString stringWithFormat]) then you'll have an autorelease reference, which means it could be released at some time in the future by other code - so it is vital that if you need to keep it around beyond the immediate function that you retain it. If you don't, the memory may remain allocated while you are using it, or be released but coincidentally still valid, during your emulator testing, but is more likely to be released and show up as bad access errors when running on the device.

The best way to track these things down, and a good idea anyway (even if there are no apparent problems) is to run the app in the Instruments tool, especially with the Leaks option.

A major cause of EXC_BAD_ACCESS is from trying to access released objects.

To find out how to troubleshoot this, read this document: DebuggingAutoReleasePool

Even if you don't think you are "releasing auto-released objects", this will apply to you.

This method works extremely well. I use it all the time with great success!!

In summary, this explains how to use Cocoa's NSZombie debugging class and the command line "malloc_history" tool to find exactly what released object has been accessed in your code.

Sidenote:

Running Instruments and checking for leaks will not help troubleshoot EXC_BAD_ACCESS. I'm pretty sure memory leaks have nothing to do with EXC_BAD_ACCESS. The definition of a leak is an object that you no longer have access to, and you therefore cannot call it.

UPDATE: I now use Instruments to debug Leaks. From Xcode 4.2, choose Product->Profile and when Instruments launches, choose "Zombies".

An EXC_BAD_ACCESS signal is the result of passing an invalid pointer to a system call. I got one just earlier today with a test program on OS X - I was passing an uninitialized variable to pthread_join(), which was due to an earlier typo.

I'm not familiar with iPhone development, but you should double-check all your buffer pointers that you're passing to system calls. Crank up your compiler's warning level all the way (with gcc, use the -Wall and -Wextra options). Enable as many diagnostics on the simulator/debugger as possible.

In my experience, this is generally caused by an illegal memory access. Check all pointers, especially object pointers, to make sure they're initialized. Make sure your MainWindow.xib file, if you're using one, is set up properly, with all the necessary connections.

If none of that on-paper checking turns anything up, and it doesn't happen when single-stepping, try to locate the error with NSLog() statements: sprinkle your code with them, moving them around until you isolate the line that's causing the error. Then set a breakpoint on that line and run your program. When you hit the breakpoint, examine all the variables, and the objects in them, to see if anything doesn't look like you expect.I'd especially keep an eye out for variables whose object class is something you didn't expect. If a variable is supposed to contain a UIWindow but it has an NSNotification in it instead, the same underlying code error could be manifesting itself in a different way when the debugger isn't in operation.

Not a complete answer, but one specific situation where I've received this is when trying to access an object that 'died' because I tried to use autorelease:

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

So for example, I was actually passing this as an object to 'notify' (registered it as a listener, observer, whatever idiom you like) but it had already died once the notification was sent and I'd get the EXC_BAD_ACCESS. Changing it to [[MyNetObject alloc] init] and releasing it later as appropriate solved the error.

Another reason this may happen is for example if you pass in an object and try to store it:

myObjectDefinedInHeader = aParameterObjectPassedIn;

Later when trying to access myObjectDefinedInHeader you may get into trouble. Using:

myObjectDefinedInHeader = [aParameterObjectPassedIn retain];

may be what you need. Of course these are just a couple of examples of what I've ran into and there are other reasons, but these can prove elusive so I mention them. Good luck!

Just to add another situation where this can happen:

I had the code:

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

Obviously I had forgotten to allocate memory for the string:

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

fixes the problem.

Use the simple rule of "if you didn't allocate it or retain it, don't release it".

I've been debuging, and refactoring code to solve this error for the last four hours. A post above led me to see the problem:

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

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

Goodbye EXC_BAD_ACCESS

I forgot to return self in an init-Method... ;)

Forgot to take out a non-alloc'd pointer from dealloc. I was getting the exc_bad_access on my rootView of a UINavigationController, but only sometimes. I assumed the problem was in the rootView because it was crashing halfway through its viewDidAppear{}. It turned out to only happen after I popped the view with the bad dealloc{} release, and that was it!

"EXC_BAD_ACCESS" [Switching to process 330] No memory available to program now: unsafe to call malloc

I thought it was a problem where I was trying to alloc... not where I was trying to release a non-alloc, D'oh!

NSAssert() calls to validate method parameters is pretty handy for tracking down and avoiding passing nils as well.

I've been debuging, and refactoring code to solve this error for the last four hours. A post above led me to see the problem:

Property before:

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

Property after:

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

Goodbye EXC_BAD_ACCESS

Thank you so much for your answer. I've been struggling with this problem all day. You're awesome!

In my case i had a view (A) which in i had an instance of another view (B). i had forgotten that B was subclassed from A. Obviously this leads to a recursive and endless allocation. breaking this issue fixed the EXE_BAD_ACCESS problem.

   class A: UIView {
 
      let b = B()
      .
      .
   }



   class B: A {
     .
     .
   }

EXC_BAD_ACCESS

EXC_BAD_ACCESS accessing to an object that has already been released. Kernel sends this exception(EXC), saying that block of memory cannot be accessed(BAD ACCESS).

  • [unowned(unsafe)] is used
  • when one target uses another target with different IPHONEOS_DEPLOYMENT_TARGET[About]. In my case Test target(10.0) used explicit dependency[About] with 14.0 IPHONEOS_DEPLOYMENT_TARGET

EXC_BAD_ACCESS error when trying to allocate ScrollView space of 140000xScreen Height on 12 Pro Max. It allocates fine until it reach around 140,000 pixel width. ;)

If you are using custom fonts and you are instantiate them programmatically, this error can occur if you not register the fonts in runtime previously.

To be sure if is the case, the Xcode console will print something like this:

* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x1d8)
    frame #0: 0x0000000180f969cc CoreText`CTFontGetClientObject + 12
...

or

* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)
    frame #0: 0x000000012341c10e CoreFoundation`CFRelease.cold.1 + 14
    frame #1: 0x00000001232ed7bd CoreFoundation`CFRelease + 77
    frame #2: 0x0000000128136990 libGSFont.dylib`GSFontGetExtraData + 112
    frame #3: 0x0000000135bc8958 UIFoundation`-[UIFont lineHeight] + 9
    frame #4: 0x00000001340149f3 UIKitCore`-[UILabel intrinsicContentSize] + 331
...

To register the custom fonts and solve that issue, you can checkout this solution: https://stackoverflow.com/a/69756114/3701102

Related