pop()中没有free()的链表

linked list without free() in pop()

本文关键字:链表 free pop      更新时间:2023-10-16

我浏览了许多作为堆栈工作的单链表的例子。它们有以下共同点:它们总是在pop()函数中的弹出项上使用free,例如:

struct Node  
{  
struct Node *Next;  
}*Head;  
void pop()  
{  
struct Node *cur_ptr=Head;  
....
Head = Head->Next;
// do something with cur_ptr
free(cur_ptr);  
....
}   

我总是需要使用那个规则吗?在弹出功能中没有可用项目的情况下,我可以从列表中弹出项目吗?我想要实现的是在程序启动时只分配一次列表,避免每次调用pop、push函数时都会释放和分配内存。我想要弹出项目,使用项目并再次推送它(在程序的其他部分)到列表中以供重用。这种方法有什么问题吗?

谢谢你的意见和帮助。

您必须确保在不再需要时释放分配的内存,这就是重点。

如果你失去了对动态分配地址的引用而没有释放它,那么你就会出现内存泄漏,嗯:

void pop() {
// get element from stack
// use it
// not call free
}

如果您不将弹出项目的地址存储在任何位置,这将产生泄漏。

如果你想重复使用分配的项目,那么你可以自由地这样做,在这种情况下,你不应该释放它们,例如:

void push() {
struct Node *ptr = pop_unused_node();
if (!ptr) // if no unused node is found then we need a new one
ptr = malloc(sizeof(struct Node));
*ptr = data;
push(ptr);
}
void pop() {
struct Node *ptr = pop();
// use data
push_unused_node(ptr);
}
void clearup() {
for each node in unused list
free(node);
for each node in stack
free(node);
}

我希望您看到的所有实现也能在push()中分配节点。

当然,你可以随心所欲地制作自己的流行作品;只要你在处理完节点后不要忽略释放它们。

pop()通常释放内存的原因是,从传统意义上讲,pop()操作是链表最后一次能够"查看"元素。

大多数list实现都不是侵入性的,因此您可以将一些已知的数据类型存储到list中,但list本身的内部细节是未知的。在这种方法中,list在这些实现中是有意义的——该对象的"内务细节"通常将在push()中分配,使pop()成为释放它们的逻辑位置。

由于用户可能希望检查"下一个"元素(而不将其从列表中弹出),大多数实现都有一个front()(或类似)成员函数,允许检查下一个值,而pop()只是删除该项(并且没有返回值)。

侵入性的数据结构对可以存储在其中的内容施加了更多的限制,但在手动内存管理方面也提供了更大的灵活性(如果这是你想要的)。

为什么不想释放内存?如果你不释放内存,那么你最终会泄露内存!

此外,您应该更喜欢new而不是free

而且,如果你想成为一个现代的、C++风格的人,那么你应该考虑使用std::stack。

您看到的所有实现在弹出值时都是免费的,因为它们负责内存中的该位置。如果你分配了什么,你的工作就是解除分配。

但这是编程。计算机会执行你告诉它的任何操作,所以如果你觉得这对你更有效,那就去做吧。你可以在没有内存分配或释放的情况下实现自己的链表类。我当然不建议这样做,因为我认为你会遇到更多的问题,而不是像预期的那样让列表类进行分配和解除分配,但这一切都取决于你。