如果 alloca() 函数在特定函数中被多次调用,是否可以保证由它分配的所有堆栈段完全形成堆栈内存的连续部分?
问问题
206 次
3 回答
4
也许。alloca
在 C、C++ 或 Posix中没有。它在基于 Unix 的系统中是一个常见的扩展,但每个系统都按自己的意愿定义它。(GNU 版本的文档表明它们是连续的,但我认为没有实际的保证。)
于 2013-07-03T07:58:47.980 回答
1
是否保证它分配的所有堆栈段完全形成堆栈内存的连续部分?
不,如果有保证,您可以在其文档中阅读所有相关信息。alloca
是一个实现定义的函数(唯一能告诉你有什么保证的是你的编译器的实现者)。
它也是非标准的、不安全的和不可移植的(基本上比在 C++ 中使用malloc
and更糟糕)。free
除非您想知道遗留代码(使用它)的行为方式,否则使用它的唯一想法就是代码质量较低。
于 2013-07-03T08:06:25.410 回答
1
正如其他人所说,简短的回答是“不”。
然而,阅读实施者文档甚至逆向工程可以让您做出这样的假设(或不做出)。
我在cpp.sh上运行了这个示例,它说void*
大小为 8,差异为 (-32):
// Example program
#include <iostream>
#include <string>
#include <alloca.h>
#include <stdint.h>
int main()
{
void *var1 = alloca(sizeof var1);
std::cout << "sizeof var1: " << sizeof var1 << std::endl;
std::cout << "var1 addr: " << var1 << std::endl;
void *var2 = alloca(sizeof var2);
std::cout << "var2 addr: " << var2 << std::endl;
intptr_t diff = (intptr_t)var2 - (intptr_t)var1;
std::cout << "addr diff: " << diff << std::endl;
}
嗯。不连续。也许有一些简单的填充正在进行。
分配大小为 128 字节的 diff 为 (-144):
// Example program
#include <iostream>
#include <string>
#include <alloca.h>
#include <stdint.h>
int main()
{
int size = 128;
void *var1 = alloca(size);
std::cout << "var1 addr: " << var1 << std::endl;
void *var2 = alloca(size);
std::cout << "var2 addr: " << var2 << std::endl;
intptr_t diff = (intptr_t)var2 - (intptr_t)var1;
std::cout << "addr diff: " << diff << std::endl;
}
嗯。对齐不限于 32 字节...
进一步的逆向工程作为学生练习留下。
(仅通过两个测试,我就可以很好地猜测没有任何文档的情况。再做几个测试应该会缩小很多。)
于 2018-05-17T17:14:03.323 回答