返回分配指针

Posted

技术标签:

【中文标题】返回分配指针【英文标题】:returning alloca pointer 【发布时间】:2011-10-26 07:30:06 【问题描述】:

此代码是否返回对堆栈上分配的变量的无效引用?或者什么:

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

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

【问题讨论】:

除了你的问题,alloca 可能总是返回一个无效的指针,你真的无能为力。使用alloca 的代码几乎可以肯定是错误代码,并且可能存在严重漏洞。 致 R.:这个“使用 alloca 的代码几乎可以肯定是错误的代码”是类似于“任何刀的使用都是错误的”或类似的陈述。 alloca 在响应式和有目的的使用时是一个强大的功能。 【参考方案1】:

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

alloca() 函数在栈帧中分配 size 个字节的空间 来电者的。此临时空间会在 调用 alloca() 的函数返回给它的调用者

【讨论】:

【参考方案2】:

这个:

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

就是这样:

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

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

【讨论】:

【参考方案3】:

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

【讨论】:

【参考方案4】:

根据Linux manual page:

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

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

【讨论】:

【参考方案5】:

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

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

【讨论】:

【参考方案6】:

我自己从未使用过 alloca,但我在这里读到了“内联问题”: Why is the use of alloca() not considered good practice?

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

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

【讨论】:

以上是关于返回分配指针的主要内容,如果未能解决你的问题,请参考以下文章

指针做参数的动态内存分配与二重指针(上)

在方法中返回向上转换的指针时替代堆分配

如何从函数返回动态分配的指针数组?

分配并返回一个二维数组指针,其中行和列是运行时参数

c++中函数中变量内存分配以及返回指针引用类型的思考

当返回可能在 C++ 中的堆栈上分配的成员时,最好的指针/引用类型是啥?