C编程:malloc并在循环中自由

kou*_*uei 6 c malloc free

我刚开始用C和有关于性能问题知之甚少malloc()free().我的问题是这样的:如果我在一个循环中调用,malloc()然后循环,例如,20次迭代,它会比在循环调用运行得慢吗?free()whilefree()

我实际上使用第一种方法将内存分配给缓冲区,从文件中读取可变长度字符串,执行一些字符串操作,然后在每次迭代后清除缓冲区.如果我的方法导致很多开销,那么我想要求一个更好的方法来实现相同的结果.

ken*_*ytm 15

绝对慢.(但是,请记住,你需要平衡的数量mallocfree否则你会得到一个内存泄漏.)

如果长度不同,您可以使用realloc扩展缓冲区大小.

void* v = malloc(1024);
size_t bufsize = 1024;

while(cond) {
   size_t reqbufsize = get_length();
   if (reqbufsize > bufsize) {
      bufsize = reqbufsize * 2;
      v = realloc(v, bufsize);
   }
   // you may shrink it also.

   do_something_with_buffer(v);
}

free(v);
Run Code Online (Sandbox Code Playgroud)

  • @BillyONeal:这实际上是一种非常常见的做事方式. (5认同)
  • 缓冲区通常与其旧的大小成比例地增加,因为它得到更好的摊销渐近运行时间.如果每个realloc添加一个插槽并插入n个元素,则需要1 + 2 + ... +(n - 1)+ n = O(n ^ 2)个副本.但是,如果将缓冲区大小加倍,则插入n个元素只需要O(1)个副本.您可以通过查看哈希表维基百科文章找到更严格的解释:http://en.wikipedia.org/wiki/Hash_table#Resizing_by_copying_all_entries (3认同)
  • +1 - 但你不觉得`bufsize = reqbufsize*2;`有点激烈吗?:P (2认同)
  • @Arthur.是.但是,如果`realloc`失败,你会遇到比泄漏更大的问题:). (2认同)

Cas*_*bel 7

如果你在里面调用malloc,你不能在循环外调用:

char * buffer;
for (int i = 0; i < num_files; i++) {
    buffer = malloc(proper_length(i));
    // do some things with buffer
}
free(buffer);
Run Code Online (Sandbox Code Playgroud)

你将有malloc'ed num_files时间,但只释放一次 - 你泄露了除了最后一个以外的所有内存!

如果你知道一个适用于所有东西的大小,或者使用realloc,有两个主要的选择 - 循环前的malloc(或者只是使用一个数组):

char * buffer = NULL;
for (int i = 0; i < num_files; i++) {
    buffer = realloc(proper_length(i));
    // do some things with buffer
}
free(buffer);
Run Code Online (Sandbox Code Playgroud)


Ste*_*sen 6

对于20次迭代,您不应该担心malloc/free的性能.

即使对于更多(几个数量级),您也不应该开始考虑优化,直到您分析代码并了解什么是缓慢的.

最后,如果您要释放缓冲区,则无需先清除缓冲区.即使您要在循环外移动malloc/free(使用Justin建议的最大缓冲区),您也不需要显式清除缓冲区.