C++ pop()中不带free()的链表

C++ pop()中不带free()的链表,c++,stack,singly-linked-list,C++,Stack,Singly Linked List,我浏览了许多单链表的示例,它们可以作为堆栈使用。它们有以下共同点:它们总是对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()函数中的弹出项使用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函数中没有可用项目吗? 我想要实现的是在程序启动时只分配列表一次,避免每次调用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()中分配节点


当然,你可以用任何你想要的方式制作自己的流行音乐作品;只要在处理完节点后不忽略释放节点。

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

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

而且,如果你想成为一个现代化的C++语言的人,那么你应该考虑使用。

为什么
pop()
通常会释放内存是因为传统意义上的
pop()
操作是链表最后一次能够“看到”元素

大多数
列表
实现都不是侵入式的,因此您可以将您知道的某些数据类型存储到
列表
中,但是
列表
本身的内部细节是未知的。在这种方法中,
列表
是有意义的。在这些实现中,该对象的“内务管理细节”通常会在
push()
中分配,从而使
pop()
成为释放它们的逻辑位置

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


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

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


但这是编程。电脑会做你告诉它的任何事情,所以如果你觉得这对你更好,就去做吧。您可以实现自己的链表类,而无需内存分配或释放。我当然不会推荐它,因为我认为如果你只是让list类按原意分配和取消分配,你会遇到更多的问题,但是,这一切都取决于你。

设计是c(不是c++),我同意@DieterLücking,无论是设计还是标记都是误导性的。根据真正的目标语言,方法会有很大的不同。