在C/ c++中,链表只有头指针分配在堆栈中,其他节点分配在堆中.这可能导致内存泄漏

In C/C++, linked list has only head pointer allocated in stack and other nodes allocated in heap. This may cause memory leak?

本文关键字:分配 泄漏 内存 节点 其他 链表 堆栈 指针 c++      更新时间:2023-10-16

对于C和c++,有一个指针指向它的头节点的链表。但是,所有节点都是通过malloc()或new在堆上分配的。当头指针超出其作用域(例如其函数退出)时,堆上分配的所有节点将丢失。对吧?这是内存泄漏吗?

C/c++如何处理这类问题?它自动调用deallocator ?(例如free()或delete)?

处理这类事情的更好方法是使用标准容器,而不是一些自制的东西,除非你有很好的理由&知道你在做什么,为什么…

std:: vector<>
std:: list<>

但是在选择容器时,重要的是要知道你在做什么,它的生命周期应该是多少。

@Jack -无论你做什么,标准容器都不会神奇地为你处理手动分配的对象。那根本不可能。

您必须改变处理问题的方法,将问题视为"手动分配的对象"。一旦您完成了这个飞跃,并且意识到这是一个不好的方法,那么您可以在"它们是值对象"或"它们将由shared_ptr管理"之间进行选择。

EX1:使用shared_ptr来保存新对象(如果在MyNode周围复制是一个坏主意[性能,拥有的资源,保留的状态]):

void MyFunction()
{
  typedef boost::shared_ptr<MyNode> NodePtr;
  std::list<NodePtr> my_list;
  my_list.push_back(NodePtr(new MyNode(args...)));
  my_list.push_back(NodePtr(new MyNode(args...)));
  ...
  // when this function exits, the nodes, which are owned by shared_ptr's
  // which are themselves owned by a stack instance of std::list<> 
  // will be automatically deleted, no leaks anywhere...
}

EX2:如果你的节点很便宜,可以被视为可复制的对象(值语义),你就会这样做:

void MyFunction()
{
  std::vector<MyNode> my_list;
  my_list.push_back(MyNode(args...));
  my_list.push_back(MyNode(args...));
  ...
  // when this function exits, the nodes, which are shored directly as copies
  // in the vector container, will be automatically deleted, no leaks anywhere...
}

如果出于某种原因你真的想手动管理实例(通常你这样做是因为生命周期并不真正绑定到单个容器的生命周期,而是有一些不规则的生命周期,除了自定义算法之外不能被整齐地封装):

void MyFunction()
{
  std::list<MyNode*> my_list;
  my_list.push_back(new MyNode(args...));
  my_list.push_back(new MyNode(args...));
  ...
  // we must manually deallocate the nodes because nothing else has been given
  // responsibility anywhere (we're manually managing them)
  typedef std::list<MyNode*>::iterator iterator;
  for (iterator it = std::begin(my_list), end = std::end(my_list); it != end; ++it)
    delete *it;  // manually releases our allocated memory from the heap
  // the "head" is still deleted automatically because it is stack allocated
  // (the list object)
}

如果您不再有方法访问节点(并且它们仍然在内存中),那么是的,这是泄漏。语言本身不以任何方式处理内存泄漏,然而现代操作系统在进程结束后进行清理,因此内存泄漏确实(最终)得到解决,但只是在进程执行结束时。(但是,不要依赖于操作系统在你完成后进行清理)对于程序员来说,这是一件很可怕的事情。

是的,这是内存泄漏。不,无论是C还是c++(没有C/c++这样的语言)都没有任何机制来处理这个问题。它们不是JAVA或更高版本的语言。这取决于你,作为一个程序员。