【问题标题】:Is it a good idea to use C99 VLA compared to malloc/free?与 malloc/free 相比,使用 C99 VLA 是个好主意吗?
【发布时间】:2011-03-06 03:47:30
【问题描述】:

使用 C99 VLA 是个好主意吗?与 malloc/free 相比,何时使用 VLA 更合适? (因为 VLA 可能会炸毁堆栈?)

【问题讨论】:

  • 避免无法解释的 TLA,例如 VLA...
  • @Thomas:“VLA”一词在 C99 的上下文中具有一个公认的、众所周知的含义。能够回答问题的人会知道这意味着什么。

标签: c c99


【解决方案1】:

堆栈分配的主要优点是您可以获得分配的可变长度数组的自动内存管理。由于内存管理是任何 C 程序的核心挑战之一,如果可以的话,您绝对应该使用 VLA 来简化您的任务。

然后,我将主张您应该尽可能一致地使用 VLA,否则仅在以下情况下使用 malloc:您需要控制存储的持续时间,如果您有非常大的分配,并且如果您想处理 out-优雅的内存错误。

【讨论】:

  • “非常大”有多大\o/
【解决方案2】:

是的,除非您知道自己的筹码量会爆炸。如有必要,您还可以更改堆栈的大小,每个操作系统的方式都不同,但这是可能的。 VLA 的优点是:

  • 快速:调整堆栈指针和/或帧指针无论如何都会完成,因此 VLA 的成本几乎为 0。

  • 简单:一个简单的定义,没有初始化指针,检查释放并且没有内存泄漏的风险。

  • 它是自动线程安全的,因为每个线程都有自己的堆栈。它还具有更好的扩展性,因为不需要锁定,这是使用malloc/free 时可能出现的一个问题。

  • 可读性:这确实是一个简单的概念,因此不太可能引入细微的错误。

它有一些缺点:

  • 大小有限:如前所述,堆栈可能会爆炸。

  • 缓冲区溢出比堆内存要严重一些(可以说这是一种优势,因为崩溃的应用程序比默默地破坏数据并最终在不相关的指令上崩溃的应用程序要好)。

  • 可移植性:并非所有编译器都实现了它,但它通常可以由alloca 模拟(注意语义有点不同,但并不严重)。

【讨论】:

  • 如果使用alloca()(+1) 进行模拟,则不能使用sizeof,它通常隐藏在宏中。
【解决方案3】:

有关 C99 相关链接的良好列表(包括指向可变长度数组信息的链接),请参阅:

Xcode 现在默认使用 C99 - 那么 C99 是什么?

http://lists.apple.com/archives/xcode-users/2008/May/msg00665.html

【讨论】:

    【解决方案4】:

    C++ 不支持 VLA。因此,如果需要的话,将代码移植到 C++ 会稍微费点力气。

    再一次,有些人认为这实际上是一件好事,并狡猾地提出“类”作为 c 中符号的美妙名称:-)

    【讨论】:

    • some believe this is actually a good thing and cunningly propose "class" as a wonderful name for a symbol in c :-) : 好吧,当一个人无法变得更好时,最好的获胜方式就是试图破坏比赛......
    【解决方案5】:

    只是添加另一个方面(不是直接答案,因为不涉及 malloc/free,但仍然相关):

    //
    // File: someheader.h
    //
    // Description: Some header intended to be usable in C  a n d  C++.
    //              (skipping include guards only for brevity!)
    //
    
    #ifdef __cplusplus
    extern "C"
    {
    #endif
    
    void f(size_t n, int(*)[n]); // OOPS: not supported by C++...
    
    #ifdef __cplusplus
    }
    #endif
    

    所以这不仅仅是因为porting,而是一个更普遍的兼容性问题......

    如果你需要这样的兼容性,你需要跳过 VLA。

    【讨论】:

      【解决方案6】:

      如果您的项目仅使用符合 C99 的编译器进行编译,那么使用 C99 VLA 是一个好主意,而替代方法是使用 alloca()。不应在通常使用 malloc() 的地方使用 VLA,如果您不知道 alloca() 的作用以及可能遇到的问题,则不应使用 VLA。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-02-10
        • 1970-01-01
        • 2013-03-09
        • 1970-01-01
        • 1970-01-01
        • 2010-11-05
        • 2017-05-06
        相关资源
        最近更新 更多