I have been working on a project for some time now, and I decided to make the jump to ARC. I came across some code that was bombing out every time, and I would like to know why. I have managed to simplify it down to this snippet:
typedef __strong id MYID;
int main(int argc, char *argv[])
{
MYID *arr = (MYID *) malloc(sizeof(MYID) * 4);
arr[0] = @"A"; // always get an EXEC_BAD ACCESS HERE
arr[1] = @"Test";
arr[2] = @"Array";
arr[3] = @"For";
// uh oh, we need more memory
MYID *tmpArray = (MYID *) realloc(arr, sizeof(MYID) * 8);
assert(tmpArray != NULL);
arr = tmpArray;
arr[4] = @"StackOverflow"; // in my actual project, the EXEC_BAD_ACCESS occurs here
arr[5] = @"Is";
arr[6] = @"This";
arr[7] = @"Working?";
for (int i = 0; i < 8; i++) {
NSLog(@"%@", arr[i]);
}
return 0;
}
I'm not quite sure what is happening here, tired this in 4 different projects, and they all fail. Is there something wrong with my malloc
call? Sometimes it returns null, and other times it returns a pointer that I can't access.
The crash is because you're casting malloc'd memory to a C array of objects. The moment you try to assign to one of the slots, ARC will release the previous value, which will be garbage memory. Try using
calloc()
instead ofmalloc()
to get zeroed memory and it should work.Note that your
realloc()
call will also not zero-fill any new memory that's allocated, so if you need therealloc()
then you may want to be using a temporaryvoid*
pointer that you then zero-fill manually before assigning to your object array.The
malloc
function does not zero the memory it allocates. The memory can contain random garbage.From the Clang Automatic Reference Counting guide, section 4.2:
So what's probably happening here is
malloc
is returning memory that contains random non-zero values. ARC tries to use that random value as a pointer to an object and release it, but it's not a valid object pointer. Crash.