【问题标题】:C modern array allocation?C现代数组分配?
【发布时间】:2015-07-01 16:09:36
【问题描述】:

我有一些代码来创建一个新结构并为结构数组分配一些空间。最初,我为数组上的 1 个结构分配空间:

static int datasetCount = 0;

int datasetgroup_new(DatasetGroup *dg char *id){

  dg->id = id;

  // Allocate space for a single dataset to start with
  dg->datasets = (Dataset *) malloc(sizeof(Dataset));

  return 0;

}

然后我有一个函数可以将另一个结构('dataset')添加到包含数组的结构中。在函数结束时,我重新分配数组以提供另一个空间:

void datasetgroup_add(DatasetGroup *dg, string filePath){

  // Create the dataset
  Dataset ds;
  dataset_new(&ds, filePath);

  // Copy the dataset to the dataset array
  dg->datasets[datasetCount] = ds;

  // Increment the dataset counter
  datasetCount++;

  //Grow the array
  dg->datasets = (Dataset *)realloc(dg->datasets, sizeof(Dataset) * (datasetCount + 1));

}

我一直在阅读暗示在现代 C 中你不需要做这样的事情的东西。 我可能是错的......那么更现代/更正确的方法是这样做吗?

编辑:

抱歉,为了清楚说明我没有使用 C++ 类型,我为 string 创建了一个 typedef:

typedef char* string;

【问题讨论】:

  • 你在哪里读到的?在 C++ 中,你有 newdelete,但在 C 中没有这样的东西。
  • 通常该方法对 C 是正确的。您可以使用一个库来隐藏所有麻烦。
  • 而且,如果您实际使用 C++,我建议您查看标准 containers library 并使用更适合您特定需求的容器
  • 不,字符串是:typedef char* string。对不起,我会编辑得更清楚
  • 但这只是一个帮助器,一个包装器,它在内部执行与您代码中相同的无聊操作。

标签: c arrays struct


【解决方案1】:

正如here 所提到的,在现代 C (C11) 标准中没有这方面的内容,但您可以使用像 Glib 这样的库来简化内存管理,或者您可以使用像 array 这样的数据结构。

如果您使用 Visual Studio,您可能会在其中找到一些非标准功能。

在 linux 中更具体地说明,这些函数只是 brk() 系统调用的包装器,它们都在用户空间进行内存管理,它们的速度和效率取决于它们的算法,例如 GNU C 库在堆中获得一些空间然后为您管理它,因此您的所有realloc() 调用都不会结束到brk() 系统调用,所以不要太担心它们的效率。您可以使用valgrind 来查看您的内存分析。

【讨论】:

    【解决方案2】:

    我不清楚你所说的现代 C 是什么意思,但是我想在代码中提到两件事。

    realloc的使用方式不对。如果它失败并返回 NULL,那么原始内存将被泄漏。例如,请参阅Dynamic arrays: using realloc() without memory leaks

    内存增长的逻辑调用realloc,因此每次添加时都会调用内存分配(即调用datasetgroup_add)。它将动态数组的大小/容量增加一。这可能并不理想。增加此类内存的常用习惯用法是在容量满时将其翻倍。这样,所有调用的内存分配成本为amortized (What is amortized analysis of algorithms?)。

    【讨论】:

    • 你的意思是amortized而不是memoized?
    • 是的,毫无疑问。谢谢!
    • @Arun 谢谢。您的 cmets 对 realloc 的使用很有帮助。对于增长的内存,我知道这是相对昂贵的,但是在这个程序的上下文中,这个数组完全填充后所需的处理时间远远大于填充数组的成本。
    猜你喜欢
    • 2020-07-06
    • 1970-01-01
    • 1970-01-01
    • 2020-08-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多