3

如果 alloca() 函数在特定函数中被多次调用,是否可以保证由它分配的所有堆栈段完全形成堆栈内存的连续部分?

4

3 回答 3

4

也许。alloca在 C、C++ 或 Posix中没有。它在基于 Unix 的系统中是一个常见的扩展,但每个系统都按自己的意愿定义它。(GNU 版本的文档表明它们是连续的,但我认为没有实际的保证。)

于 2013-07-03T07:58:47.980 回答
1

是否保证它分配的所有堆栈段完全形成堆栈内存的连续部分?

不,如果有保证,您可以在其文档中阅读所有相关信息。alloca是一个实现定义的函数(唯一能告诉你有什么保证的是你的编译器的实现者)。

它也是非标准的、不安全的和不可移植的(基本上比在 C++ 中使用mallocand更糟糕)。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 回答