我一直在做一个项目已经有一段时间了,我决定跳到ARC。 我偶然发现了一些轰炸的代码,我想知道为什么。我已设法将其简化为此代码段:
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;
}
我不太确定这里发生了什么,在4个不同的项目中厌倦了这一点,而且都失败了。我的malloc
电话有问题吗?有时它返回null,有时它返回一个我无法访问的指针。
答案 0 :(得分:13)
崩溃是因为您将malloc内存转换为C对象数组。当您尝试分配给其中一个插槽时,ARC将释放先前的值,这将是垃圾内存。尝试使用calloc()
代替malloc()
来获取归零内存,它应该可以正常工作。
请注意,您的realloc()
调用也不会对任何已分配的新内存进行零填充,因此如果您需要realloc()
,那么您可能希望使用临时void*
在指定对象数组之前,手动零填充的指针。
答案 1 :(得分:8)
malloc
函数不会将其分配的内存归零。内存可能包含随机垃圾。
从Clang Automatic Reference Counting指南,第4.2节
对于
__strong
个对象,首先保留新的指针;第二,左值加载了原始语义;第三,新的指针被存储到具有原始语义的左值中;最后,旧的指针被释放。
所以这里可能发生的是malloc
返回包含随机非零值的内存。 ARC尝试使用该随机值作为指向对象的指针并释放它,但它不是有效的对象指针。崩溃。