请解释我崩溃的原因。我有第三方代码意外崩溃与EXC_BAD_ACCESS
static int overwrite_selector(struct srm_target *srm, MARFileRemoverProgressBlock progressBlock)
{
srm->buffer = (unsigned char *)alloca(srm->buffer_size);
if(overwrite_byte(srm, 1, 0xF6, progressBlock) < 0) return -1;
return 0;
}
static int overwrite_byte(struct srm_target *srm, const int pass, const int byte, MARFileRemoverProgressBlock progressBlock)
{
memset(srm->buffer, byte, srm->buffer_size);
return overwrite(srm, pass, progressBlock);
}
线路memset发生崩溃(srm-&gt;缓冲区,字节,srm-&gt; buffer_size);所以srm-&gt;缓冲区的分配内存似乎有问题。但是,如果我将alloca替换为malloc,则一切正常(没有崩溃)。
我开发osx 10.9 ARC启用
我注意到Apple特有的一点:如果我在全局队列中运行代码但是如果在主队列中一切正常,则会发生崩溃。
答案 0 :(得分:3)
听起来像是堆栈溢出,alloca will allocate from the stack所以如果你试图分配太多会导致堆栈溢出,而malloc将从堆中分配更大的堆。无法知道when you overflow the stack with alloca。
另请注意,由于alloca
在堆栈上分配,因此返回该函数的内存将无法工作,因为退出该函数后该内存将不再可用。因此,如果您需要使用函数外部的内存,则需要使用malloc
。
答案 1 :(得分:3)
这里你在函数中分配内存,
static int overwrite_selector(struct srm_target *srm, MARFileRemoverProgressBlock progressBlock)
{
srm->buffer = (unsigned char *)alloca(srm->buffer_size);
if(overwrite_byte(srm, 1, 0xF6, progressBlock) < 0) return -1;
return 0;
}
并且由于您使用alloca
,因此在函数返回时将释放分配的内存。当你从其他功能使用它时会导致程序崩溃
在这里,您在函数分配内存中调用了其他函数。所以原因似乎是stackoverflow。并且无法从alloca
了解这种情况。由于在stackoverflow上alloca
的这种未定义的行为,它被告知在这种情况下使用alloca
并不好。
答案 2 :(得分:2)
由于alloca
尝试在堆栈上分配字节,因此了解堆栈大小是很重要的。你可以用这样的代码检查堆栈大小的限制
#include <sys/resource.h>
void checkStackSize( void )
{
struct rlimit limits;
if ( getrlimit( RLIMIT_STACK, &limits ) == 0 )
printf( "soft_limit=%lld hard_limit=%lld\n", limits.rlim_cur, limits.rlim_max );
}
当我在osx上测试时,软限制为8MB,硬限制为64MB。在iOS设备上,两个限制均为1MB。
注意:以下内容来自alloca的手册页
alloca()依赖于机器和编译器;不鼓励使用它。
alloca()稍微不安全,因为它无法确保指针 返回有效的和 可用的内存块。所做的分配可能会超出堆栈的范围,甚至可能更进一步 到内存中的其他对象,而alloca()无法确定这样的错误。避免alloca()大 无限制的分配。