Allocating too much memory kills my App rather than returning NULL
Allocating too much memory kills my App rather than returning NULL
- Subject: Allocating too much memory kills my App rather than returning NULL
- From: Don Quixote de la Mancha <email@hidden>
- Date: Fri, 04 Nov 2011 18:40:30 -0700
My iOS App Warp Life is an implementation of the Cellular Automaton
known as Conway's Game of Life:
http://www.dulcineatech.com/life/
The game takes place on a square grid. Each square is known as a
"Cell", with the Dead or Alive state of the Cell being indicated by a
single bit to conserve memory.
I store the grid as an array-of-arrays rather than a two dimensional
array. That is, I have an array of pointers which has the same number
of elements as there are rows. Each row is array of unsigned longs,
with the number of elements being the number of columns divided by
thirty-two.
The user can set the size of the grid in my Settings view. I attempt
but fail to allow the user to make the grid as large as the available
memory will allow.
My code checks that calloc() returns valid pointers for each
allocation attempted when creating a new grid. If all the allocations
succeed, I copy the data in the old grid into the center of the new
one, then free() each array in the old grid.
If calloc() ever returns NULL while attempting to allocate the new
grid, I back out all of the successful allocations by passing each
array pointer to free(). Then I display an alert to the user to
advise them that there is not enough memory for their desired grid
size, and suggest trying a smaller one.
This all works great when I run it in the Simulator with Xcode 4.2.
I'm pretty sure I've had this work in the Simulator in several
previous versions of Xcode.
In iOS 3.1.2 on a first-generation iPhone, 3.2 on a first-gen iPad and
4.3 on an iPhone 4, my App terminates before calloc() ever returns
NULL!
I have not yet tried with iOS 5 or the 5.0.1 betas, but even if this
is an iOS bug that has been fixed, I would much rather work around it
as I do not want to require my users to upgrade their firmware just to
be able to run my App. Other than this one problem everything in my
App works great all the way back to iOS 3.1.2.
Even though I feel it should not be necessary to check for Cocoa Touch
memory warnings if I am freeing all my arrays when calloc() fails, I
did try adding an application delegate as well as creating my own base
class for all my view controllers that do implement the memory warning
methods. These implementations set a global flag that indicates it is
not safe to allocate any more memory. Then instead of calling
calloc() directly, I call a custom allocation function that returns
NULL if that flag is ever set. Only after freeing all the arrays do I
reset the flag to enable further allocations.
I set breakpoints at each of the memory warning methods, but my
breakpoints are never hit. I also tried breaking on Objective-C
exceptions but no exceptions are thrown. After my App terminates, the
debugger GUI indicates that my app is paused - GDB doesn't seem to
know that my App has actually been killed. I have to press the Stop
button in Xcode to let GDB know that it's time to quit.
If y'all think this is an as-yet-unreported bug in the iOS I will be
happy to file a report, but I would be even happier if someone could
suggest a workaround. I've been beating my head against this for a
couple days now.
Thanks!
Don Quixote
--
Don Quixote de la Mancha
Dulcinea Technologies Corporation
Software of Elegance and Beauty
http://www.dulcineatech.com
email@hidden
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden