allocc函数崩溃,但malloc没有问题



请解释一下崩溃的原因。我有第三方代码意外崩溃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);
}

Crash发生在memset(srm->buffer, byte, srm->buffer_size)所以似乎有问题分配内存为srm->缓冲区。但是如果我将alloca替换为malloc,那么一切都没问题(没有崩溃)。

我在osx 10.9上开发了ARC

我注意到苹果特有的:如果我在全局队列中运行代码会发生崩溃,但如果在主队列中运行代码则一切正常。

听起来像堆栈溢出,alloca将从堆栈中分配,因此如果您试图分配太多将导致堆栈溢出,而malloc将从更大的堆中分配。没有办法知道你什么时候用alloca溢出堆栈。

另外,请注意,由于alloca在堆栈上分配,从函数返回的内存将不起作用,因为一旦退出函数,该内存将不再可用。因此,如果您需要使用函数外的内存,则需要使用malloc

这里你在函数中分配内存,

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中无法得知这种情况。由于alloca在stackoverflow上的这种未定义的行为,在这种情况下使用alloca是不好的。

由于alloca尝试在堆栈上分配字节,因此了解堆栈大小非常重要。您可以使用如下代码检查堆栈大小的限制

#include <sys/resource.h>
void checkStackSize( void )
{
    struct rlimit limits;
    if ( getrlimit( RLIMIT_STACK, &limits ) == 0 )
        printf( "soft_limit=%lld hard_limit=%lldn", limits.rlim_cur, limits.rlim_max );
}

当我在osx上测试时,软限制是8MB,硬限制是64MB。在iOS设备上,这两个限制都是1MB。

注意:以下内容来自alloca

的手册页

alloca()依赖于机器和编译器;不鼓励使用

alloca()有点不安全,因为它不能确保指针返回指向一个有效的和的点可用的内存块。所做的分配可能超出堆栈的边界,甚至更远进入内存中的其他对象,并且alloca()无法确定这样的错误。避免alloca()使用large无界分配。

相关内容

  • 没有找到相关文章

最新更新