我应该教我的学生阿洛卡吗?[关闭]


18

alloca在现实世界中使用得如何?在合理的时候我应该教我的学生使用alloca吗?还是我应该教他们不要使用它?来自C ++ RAII背景,不必free手动调用的想法听起来很有希望,尤其是在具有多个出口点的函数中。



8
为什么不教他们C99 VLA?

@cnicutar alloca()与实现有关,但是至少有许多实现在失败时返回NULL。C99 VLA无法指示故障。
复杂请参见bio

2
@sbi:对于SO来说,这是一个开放式的问题,它实际上并不适合闭门造车者认为SO帖子应该采用的格式。太主观了,没有明确的答案,只有意见。这很好,但不适用于SO。还要注意,出于对OP代表的尊重,没有人拒绝投票,我们只是关闭了这个问题作为主题。
保罗·萨西克

1
@PascalCuoq无论如何,您都不应该为alloca / VLA分配很多资源。如果不确定当前上下文中的“很多”,请使用malloc

Answers:


31

如果你持有的一般C编程的课程,你不应该教给他们的事,是不是标准。初级程序员不必要地编写非标准和/或非便携式代码,因为它们是通过这种方式来学习的,这在过去20到30年左右的时间里一直是软件行业的一个巨大问题。不教给他们标准的代价,仅是标准就没有什么可能是天文数字。

如果您正在学习算法或应用程序编程方面的高级课程,那么最好提一下。另一方面,我已经编写了15年的程序,从硬实时嵌入式应用程序到Windows应用程序启动程序,都从未使用过该功能。


我所见过的唯一用它做不到的另一种方法是在某些版本的Windows上执行堆栈粉碎检测,其中alloca失败表示剩余空间不足,或者它可能只有一些粗糙的ASM来捕获崩溃; 自从我看过这段代码已有一段时间了。它起作用了,但是有点恐怖。
Donal Fellows 2013年

13

我可以看到发生了两件事:

  1. 学生了解的影响alloca,了解堆栈和堆之间的区别,并alloca谨慎使用。(不太可能)

  2. 学生认为“哇,这就像malloc不用担心free,”,请过度使用它,导致堆栈溢出,不知道发生了什么。

我认为如果您描述会更好alloca,然后运行以下代码:

#include <malloc.h>

int OverflowMyStack(int start) {
    if (start == 0)
        return 0;

    char * p = (char *)_alloca(4096);
    *p = '0';
    return OverflowMyStack(start - 1);
}

int main () {
    return OverflowMyStack(512);
} 

资料来源:http : //www.strchr.com/alloca

向他们展示危险,然后告诉他们不要使用它。他们仍将了解堆栈与堆的关系,了解实际的危险,并且可以继续使用标准的东西。


1
我认为即使向他们展示了示例代码,大多数学生仍然属于第二类。
右对齐

@WTP-可能是,但这就是为什么即使告诉他们可能发生的事情,您还是告诉他们不要使用它。
BlackJack

4
为什么该代码使用_alloca而不是alloca?为何要转换结果?
基思·汤普森

5

这个问题的答案应该基于 您的目标

您是否要教一个已经知道如何编程如何编写C并在野外使用现有C代码的人?如果是这样,请介绍alloca以及您想要的其他任何内容。

另一方面,如果您要讲授的入门课程仅是巧合地使用C(并且由于C是非常小的语言,等等),则应重点关注重要部分(编写模块化程序,子例程,集合等)。 )。从学生的角度来看,alloca是多余的,因为在大多数情况下malloc足够了,从良好的代码角度来看,您最好明确地提到手动内存管理如何令人讨厌以及其他语言如何解决此问题。毕竟,还有更多内存管理,然后是alloca或RAII,所以您真的不应该局限于这些,并且正如您已经提到的那样,如果将alloca与其他“更标准”的方法用其他语言进行处理相比,则更容易理解alloca的目的。 (或C99 ...)


2

没有。

C程序员甚至应该意识到alloca的存在的唯一原因是理解并修复正在使用它的遗留代码。

的任何使用alloca

  1. 无用的,即可以用自动存储持续时间的固定大小变量轻松地替换它,或者
  2. 危险的堆栈溢出等待发生。

除了一些我从未发现任何真实示例的思想实验之外,没有针对alloca(或VLA)既没有用处也没有脆弱性的使用案例(上述两种情况之一)。


2
当然,绝对没有人能够负责任地使用它。没有永不。
DeadMG

唯一的“负责任”使用alloc是100%等效于固定大小的自动阵列,并且不那么便携。
R .. GitHub停止帮助ICE,

那么,我想没人会想要分配一些动态量,例如几千字节,这将永远不会溢出。或调用一些OS API函数,该函数将告诉他们有多少可用空间。或者只是将堆栈大小增加很多。
DeadMG

如果只有几KB,并且您确信自己有几KB,则可以使用它T foo[5000];
R .. GitHub停止帮助ICE,

仅当T具有琐碎的默认构造函数时。如果我需要精打细算,那么即使是简单的内存清零也可能要花我钱。但是其他类型可能具有更复杂的默认构造逻辑。例如,如果我想动态创建一个数组std::mutex,则可以为五千个互斥对象调用内核调用和上下文切换。不便宜。更不用说在数组后放置局部变量的额外缓存成本。
DeadMG

1

我的意见是不鼓励使用它,除非您正在教授用于为局部变量分配堆栈空间的低级编译器原理。在这种情况下教它。


0

海湾合作委员会的文件有几个实用的优点和缺点在alloca()。从实际的角度来看,大量的自由软件都在使用它,因此很高兴了解它的工作方式以及在现有代码中的使用位置。

-Wl,-stack=new-stack-size传递给gcc会增加最大堆栈大小。如果您的项目使用alloca(),或分配大型临时数组或使用递归超过特定于上下文的深度,则需要执行此操作。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.