2011-08-13 518 views
0

这段代码是否返回一个无效的引用给堆栈上分配的变量?或者是什么:返回alloca指针

void *f(size_t sz) { 
    return alloca(sz); 
} 

或者它是由ALLOCA执行/编译器支持像f(alloca(size), alloca(size))处理将是一个特例?

+1

与你的问题略有不同,但'alloca'可能总会返回一个无效的指针,并且你无能为力。使用'alloca'的代码几乎肯定是错误的代码,并且可能受到严重漏洞的影响。 –

+0

对于R .:这个“使用alloca的代码几乎肯定是错误的代码”是类似于“任何刀的使用都是错误的”或类似的声明。 alloca是响应式和有目的地使用时的强大功能。 –

回答

5

alloca在堆栈帧f中分配空间。一旦函数返回,它就不能做任何有用的事情(它不再“保留”)。

alloca()函数分配调用者的堆栈帧 中的空间大小字节。当称为alloca()的 函数返回给其调用者时,此临时空间为自动释放。

0

作为每Linux manual page

alloca()功能在 呼叫者的堆栈帧分配空间,并返回一个指针分配的块。当调用alloca() 的函数返回时,将自动释放此临时空间 。

这意味着,因为它被释放时f()返回访问由f()返回的内存企图将导致不确定的行为。

1

是的,代码返回一个无效的指针。 alloca调用不能被包装到一个函数中。如果您需要换行alloca,则仅限于宏包装。

0

正如其他人所说,它会被释放,我真的不知道如何改变行为。如果你看一个alloca如何编译基于AMD-64:

pushq %rbp 
movq %rsp, %rbp 
subq $144, %rsp 
movq %rsp, %rax 
addq $15, %rax 
shrq $4, %rax 
salq $4, %rax 
leave 
ret 

你看

1)ALLOCA实际上不是一个函数调用(因为,如你所说,那就要处理堆栈不同!)

2)无论ALLOCA确实给堆栈指针只是要获得在函数结束时惨败覆盖rbprsp

所以可能你会得到你所问的行为(无需编写程序集)?这是一个棘手的问题,我不知道,但它可能不是。

2

这样的:

void *f() { 
    char* pc4 = alloca(4); 
    ... 
} 

正是这样:

void *f() { 
    char pc4[4]; 
    ... 
} 

你也不能在函数外返回/使用PC4在第二种情况下,也可以做同样在第一种情况下。