返回分配指针
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】:
alloca
在f
的栈帧中分配空间。一旦函数返回(它不再“保留”),你就不能用它做任何有用的事情。
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?
“最令人难忘的错误之一……”的答案非常有趣。
因此,当函数超出范围时,内存肯定会被释放是不正确的。
【讨论】:
以上是关于返回分配指针的主要内容,如果未能解决你的问题,请参考以下文章