alloca可以完全替代吗?

发布于 2024-09-14 09:52:51 字数 571 浏览 11 评论 0原文

我读过很多地方说 alloca 已经过时,不应该使用,而应该使用可变长度数组。

我的问题是:alloca 是否完全可以被可变长度数组替代?

在我的特定实例中,我有一些看起来像这样的东西:

typedef struct { 
  int *value; 
  size_t size; 
  } some_type;

void SomeExternalFunction(some_type);

...

void foo(){
  //What I thought to do
  some_type bar;
  bar.value=alloca(sizeof(int)*10);
  SomeExternalFunction(bar);

  //what should be done without alloca
  some_type fizz;
  int tmp[10];
  fizz.value=tmp;
  SoemExternalFunction(fizz);
}

我是否遗漏了一些东西,或者这是alloca的实际良好用途?还假设在此示例中,出于某种原因,我希望在堆栈上分配该值

I've read quite a few places that alloca is obsolete and should not be used and Variable Length Arrays should be used instead.

My question is this: Is alloca completely replaceable by variable length arrays?

In my particular instance I have something that looks like this:

typedef struct { 
  int *value; 
  size_t size; 
  } some_type;

void SomeExternalFunction(some_type);

...

void foo(){
  //What I thought to do
  some_type bar;
  bar.value=alloca(sizeof(int)*10);
  SomeExternalFunction(bar);

  //what should be done without alloca
  some_type fizz;
  int tmp[10];
  fizz.value=tmp;
  SoemExternalFunction(fizz);
}

Am I missing something or is this an actual good use of alloca? Also assume for this example that for some reason I want for the value to be allocated on the stack

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

喜爱纠缠 2024-09-21 09:52:51

VLA 和 alloca 之间有一个重要区别:只要当前函数持续存在,alloca() 返回的内存就有效。只要 VLA 的标识符保留在范围内,VLA 占用的内存的生命周期就有效。例如,您可以在循环中分配内存并在循环外部使用内存,VLA 将消失,因为当循环终止时标识符超出范围。这意味着,您可以使用 alloca() 和足够的堆栈空间来执行此操作:

typedef struct node { int data; struct node *next; };
void fun()
{
 struct node *n=0;
 int d;
 /* Now we are building a single-linked list on the stack! */
 while(d=get_something()) {
  struct node *x=alloca(sizeof(*x));
  x->next=n; 
  x->data=d;
  n=x;
 }
 do_something_with(n);
} // and the whole thing is deleted here..

但不能使用 VLA 执行此操作。

There is an important difference between VLA's and alloca: The memory alloca() returns is valid as long as the current function persists. The lifetime of the memory occupied by a VLA is valid as long as the VLA's identifier remains in scope. You can alloca() memory in a loop for example and use the memory outside the loop, a VLA would be gone because the identifier goes out of scope when the loop terminates. This means, you can do this with alloca() and enough stack space:

typedef struct node { int data; struct node *next; };
void fun()
{
 struct node *n=0;
 int d;
 /* Now we are building a single-linked list on the stack! */
 while(d=get_something()) {
  struct node *x=alloca(sizeof(*x));
  x->next=n; 
  x->data=d;
  n=x;
 }
 do_something_with(n);
} // and the whole thing is deleted here..

You can't do this with VLAs.

白云悠悠 2024-09-21 09:52:51

alloca 完全可以被 mallocfree 取代。这需要更多的工作,但除非您非常小心,否则这是必不可少的。几乎所有使用 alloca 或 C99 vla 的代码都容易受到堆栈溢出攻击,并且在许多实现中,它们可能会导致特权提升。没有可移植的方法来知道堆栈有多大或剩余多少堆栈空间(或者编译器的内部使用或进一步的函数调用可能需要超出请求大小的多少开销),因此您可以做的唯一合理的事情是使 vla's/alloca 安全是对您支持的数据大小(例如几 kb)施加极小的人为限制。此时,您可能只使用普通的非可变长度自动对象......

alloca is completely replaceable by malloc and free. It's a little more work but unless you're very careful, it's essential. Nearly all code using alloca or C99 vla's is vulnerable to stack overflow attacks, and in many implementations, they can lead to privilege elevation. There's no portable way to know how large the stack is or how much stack space is left (or how much overhead beyond the requested size might be needed for the compiler's internal use or further function calls), so the only reasonable thing you can do to make vla's/alloca safe is impose extremely small artificial limits on the size of data you support (e.g. a few kb). At this point you might as well just be using plain non-variable-length automatic objects...

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文