从循环链表中释放已分配的内存

use*_*158 5 c linked-list

如果这是一个非常愚蠢的问题,我预先致歉。

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

我想尝试按块分配:

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;
Run Code Online (Sandbox Code Playgroud)

只要我不尝试释放任何东西(“检测到glibc:双重释放或损坏”错误),该列表就起作用。凭直觉,我认为这是因为释放它不会释放单个节点,并且以正常方式循环是试图多次释放它(加上释放整个块可能会使仍然存在的节点上的所有其他指针变了吗? ),但:

  1. 有人可以向我明确解释发生了什么吗?
  2. 有没有一种方法可以按块分配节点而不破坏对象?

这样做的目的是因为我要成千上万次调用malloc,如果事情更快,那就太好了。如果有更好的方法可以解决此问题,或者我不能指望它会更快,那么我也很高兴听到这样的消息。:)

Jen*_*edt 1

首先,在块中分配节点的方式,您始终必须使free整个块具有与从 中获得的完全相同的起始地址malloc。没办法,malloc就是这么设计的。

自行解决这个问题很复杂,而且通常不值得。现代运行时在malloc/后面有相当有效的垃圾收集free(针对其缓冲区,而不是针对用户分配),您将很难实现更好的目标,更好意味着更高效,但仍然保证数据的一致性。

在陷入这样的项目之前,先衡量一下程序的真正瓶颈在哪里。如果分配部分出现问题,还有另一种可能性更有可能是原因,即不良设计。如果您在链表中使用了如此多的元素,以至于分配占主导地位,则链表可能不是合适的数据结构。考虑使用带有移动光标的数组或类似的东西。