-1

此代码是否返回对堆栈上分配的变量的无效引用?要不然是啥:

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

或者它是由 alloca 实现/编译器支持处理的特殊情况f(alloca(size), alloca(size))

4

6 回答 6

5

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

alloca() 函数在调用者的堆栈帧中分配 size 个字节的空间。当调用 alloca() 的函数返回给它的调用者时,这个临时空间会自动释放。

于 2011-08-13T06:27:52.243 回答
2

这:

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

正是这样:

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

在第二种情况下,您既不能在函数之外返回/使用 pc4 ,也不能在第一种情况下做同样的事情。

于 2011-09-02T06:08:58.803 回答
1

根据Linux手册页

alloca()函数在调用者的栈帧中分配空间,并返回一个指向分配块的指针。alloca() 当被调用的函数返回时,这个临时空间会自动释放。

这意味着,尝试访问由返回的内存f()将导致未定义的行为,因为它在f()返回时被释放。

于 2011-08-13T06:28:30.450 回答
1

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

于 2011-08-13T06:33:09.130 回答
0

正如其他人所说,它将被释放,我真的不明白你如何改变这种行为。如果您查看allocaamd-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 对堆栈指针做什么,都会在函数结束时rbp被覆盖rsp

那么你得到你所询问的行为(不编写汇编)吗?这是一个棘手的问题,我不知道,但似乎可能不是。

于 2011-08-13T06:36:40.757 回答
0

我自己从未使用过 alloca,但我在这里读到了“内联问题”: 为什么使用 alloca() 不被认为是好的做法?

“最令人难忘的错误之一......”的答案非常有趣。

因此,当函数超出范围时,内存肯定会被释放是不正确的。

于 2011-09-02T05:59:50.383 回答