【问题标题】:C efficient way to manage function temporary dynamic memoryC 管理函数临时动态内存的有效方法
【发布时间】:2014-05-15 06:34:59
【问题描述】:

我正在制作一个非确定性有限自动机 (NFA)。一个 NFA 有一组状态,我需要四个大小相同(NFA 中的状态数)的数组来记录 NFA 模拟过程中有关状态的临时信息。

但是,不同的NFA具有不同的状态数,因此数组的大小因不同的NFA而异。

使用C我想出了三种处理内存分配的方法:

  1. 使用一个非常大的固定大小的数组。

  2. 每次调用函数时动态malloc memroy,并在函数结束前释放分配的内存

  3. 每次函数调用都使用malloc但不分配内存,使用四个静态指针变量,一个静态int arraySize记录分配的数组大小,第一次调用函数时,分配大小为NFA-的数组>numStates 并分配给每个静态指针,将 NFA->numStates 分配给 static int arraySize;第二次,如果NFA->numStates小于等于arraySize,不分配内存;如果 NFA->numStates 大于 arraySize,则释放先前的内存并重新分配大小为 NFA->numStates 的数组。

方法1使用固定大小的数组,即当输入的NFA->numStates大于硬编码的数组大小时,该函数将不起作用。

方法2适应性强,但每次调用函数都需要分配内存,效率不高?

方法3也适用,但是比较复杂,不是线程安全的?

建议或其他选择?

【问题讨论】:

  • 使用 VLA? [15 个字符]

标签: c memory-management dynamic-memory-allocation


【解决方案1】:

选项 2 怎么样,但使用 alloca(),即在堆栈上分配?它比malloc() 快​​很多(很多),并且在您离开听起来像您想要的范围时自动取消分配。

当然,它不是标准的或可移植的,所以它可能不适合你。

如果做不到这一点,固定大小的大数组似乎很容易,而且不会占用更多内存。

【讨论】:

  • alloca 受大多数环境支持,因此恕我直言,它主要是可移植的。实际上,我不知道任何不支持它的环境。放松:如果我错了,请纠正我。
  • @MichaelWalz 你几乎是对的。正如 Richard W. Stevens 在《UNIX 环境中的高级编程 2d 版》中所说,“缺点是某些系统无法支持 alloca,如果在调用函数后无法增加堆栈帧的大小”。
  • 听起来不错,但是 [stackoverflow.com/questions/1018853/… 分配导致堆栈溢出,程序行为未定义")
【解决方案2】:

Variable-Length Arrays (VLA) 从 C99 开始可用。如果您仍在使用不支持此类事物的实现,我会印象深刻。 VLA 像常规数组一样工作,只是用于声明它们的大小是在运行时确定的。这似乎就是你要找的东西。

【讨论】:

  • 听起来简单又好听。但是如果调用者给出一个无效的 n 怎么办,例如-1,还是太大导致堆栈溢出?
  • @Linlix 好吧,验证调用者给出的大小是你的工作。您可以在声明数组之前执行检查以确保大小为正。至于堆栈溢出问题:您将始终受到一些限制(malloc() 也可能导致内存耗尽)。你真的认为你的 NFA 中会有那么多州吗?如果您不打算分配一个巨大的数组(例如具有 1000000 个元素的东西),它应该不是很重要。总有一个限制,只是想想你是否会达到它 - 我个人认为你不会
  • 你说得对,我不需要那么多状态,但我正在考虑其他类似的情况。现在我决定使用固定数组,如果大小不够我使用 malloc
【解决方案3】:

当您处理任意大小的数组时,我建议您实现简单的链表结构,该结构在初始化时将保存一个预定义大小的数组,并且可以扩展以保存额外的内存块。这将是对连续内存空间的抽象。您只需要将这个结构的当前大小存储在父容器中。

#include <stddef.h>

struct contmem
{
        size_t size;
        struct memchunk
        {
                void *data;
                struct memchunk *next, *prev;
        } head;
}

因此,您可以在需要时扩展此结构,并通过迭代链表的元素来存储信息。这类似于标准 C++ 库中列表内部发生的情况,但与直接内存重新分配不同。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-09-21
    • 1970-01-01
    • 1970-01-01
    • 2011-11-14
    • 2014-01-12
    • 2011-03-06
    • 2011-09-14
    • 1970-01-01
    相关资源
    最近更新 更多