从循环链表中释放malloc的内存

时间:2011-09-24 01:49:59

标签: c linked-list

如果这是一个令人难以置信的愚蠢问题,我会事先道歉......

目前我有一个循环链表。节点数通常保持不变。当我想添加它时,我malloc了许多节点(例如100000左右)并将它拼接在一起。当我逐个malloc节点时,这部分工作正常。

我想尝试按块分配:

NODE *temp_node = node->next;
NODE *free_nodes = malloc( size_block * sizeof( NODE ) );
node->next = free_nodes;
for ( i = 0; i < size_block - 1; i++ ) {
    free_nodes[i].src = 1;
    free_nodes[i].dst = 0;
    free_nodes[i].next = &free_nodes[i+1];
}
free_nodes[size_block - 1].next = temp_node;

只要我不尝试释放任何内容('检测到glibc:双重免费或损坏'错误),该列表就可以正常工作。直觉上,我认为这是因为释放它不会释放单个节点,并且循环通过正常方式试图多次释放它(加上释放整个块可能会搞砸所有其他指针仍然存在的节点? ),但是:

  1. 有人可以明确告诉我发生了什么事吗?
  2. 有没有办法按块分配节点而不破坏东西?
  3. 这样做的目的是因为我正在调用malloc数十万次,如果事情变得更快就会很好。如果有更好的解决方法,或者我不能指望它变得更快,我也希望听到这一点。 :)

3 个答案:

答案 0 :(得分:3)

  

有人可以明确地向我解释发生了什么吗?

正是你所说的。您正在为所有块分配单个连续内存空间。然后,如果你释放它,所有内存都将被释放。

  

有没有办法按块分配节点而不破坏东西?

为每个块分配不同的内存段。在你的代码中(不完整)应该是这样的:

for ( i = 0; i < size_block ; i++ ) {
    free_nodes[i] = malloc (sizeof( NODE ));
}

答案 1 :(得分:1)

释放节点时,可以释放分配节点的整个分配。你必须以某种方式安排立即释放整个节点组。

可能你最好的办法是保留一个“免费”节点列表并重用这些节点而不是分配/释放每个节点。通过一些努力,您可以安排将节点保留在块中并首先从“最常用”块进行分配,这样如果整个块变空,您可以释放它。

答案 2 :(得分:1)

首先,您在块中分配节点的方式,总是必须free整个块具有与malloc完全相同的起始地址。没有办法解决这个问题,malloc就是这样设计的。

自己解决这个问题很复杂,通常不值得。现代运行时在malloc / free后面有非常有效的垃圾收集(对于它的缓冲区,而不是用户分配),你很难获得更好的东西,更好的意思是更有效但仍然保证数据的一致性。

在这样一个项目中失去自己之前,你的程序真正的瓶颈是什么。如果分配部分是一个问题,还有另一种可能性更可能是原因,即糟糕的设计。如果您在链表中使用了这么多元素,以至于分配占主导地位,那么链表可能不是合适的数据结构。考虑使用带有移动光标的数组或类似的东西。