简体   繁体   中英

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

For C and C++, linked list with a pointer pointing to its head node. But, all nodes are allocated on heap by malloc() or new. When the head pointer runs out of its scope eg its function exits, all nodes allocated on heap will be lost. Right? Is this a memory leak?

How C/C++ handle this kind of issue? It calls deallocator automatically? (eg free() or delete)?

The better way to handle this sort of thing is to use a standard container, instead of some homespun thing, unless you have good reason & know what you're doing, and why...

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

But to choose a container, it's important to know what you're doing, what the lifetime is supposed to be.

@Jack - no matter what you do, standard containers don't magically take care of manually allocated objects for you. That is fundamentally impossible.

You must change your approach to the problem to perceive the problem as "manually allocated objects." Once you make this leap, and realize that this is a bad way to go, then you can choose between "they're value-objects" or "they're to be managed by shared_ptr".

EX1: using shared_ptr to hold new'd objects (this is the approach to use if copying around MyNode is a bad idea [performance, owned resources, preserved state]):

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: This is what you do if your nodes are cheap, can be treated as copyable objects (value semantics):

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...
}

And if you really would rather manage the instances manually for some reason (usually you do this because the lifetimes are not really tied to a single container's lifetime, but have some irregular lifecycle that cannot be encapsulated neatly by anything but a custom algorithm):

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)
}

If you no longer have a way to access the nodes (and they are still in memory), then yes, that it a leak. The language itself does not handle memory leaks in any way, however modern operating systems do cleanup after a process has ended, so the memory leaks do (eventually) get solved, but only at the end of the process' execution. (However, do not rely on the OS to clean up after you — that's a horrible thing to do as a programmer.)

Yes, it is a memory leak. No, neither C nor C++ (there is not such language as C/C++) has not any mechanisms to handle this. They are not JAVA or later language. It is up to YOU, as a coder.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM