Clearing Linked List C#? (SOLVED)

Started by
15 comments, last by GDKnight 18 years, 6 months ago
Quote:Original post by kSquared
Quote:Original post by GDKnight
I could iterate through the nodes contained in it and set them to null but will this delete it? Im afraid it might set a reference to nothing leaving the data intact in memory.

One way is to implement the Dispose pattern.

Eh, why? Are you going to require that list elements implement IDisposable as well? Otherwise there's no point.

There's no iteration needed. As long as all node objects are unreachable from a GC root, they will be collected. This is all you need:
public class LinkedList{  private ListNode head;  private ListNode tail;  public void Clear()  {    head = tail = null;  }}

This assumes that the list doesn't hand out references to ListNode objects to external code and that it doesn't hold onto other internal references to such objects besides head and tail. If these conditions hold, the garbage collector will take care of the rest.
--AnkhSVN - A Visual Studio .NET Addin for the Subversion version control system.[Project site] [IRC channel] [Blog]
Advertisement
Quote:Original post by Arild Fines
Quote:Original post by kSquared
Quote:Original post by GDKnight
I could iterate through the nodes contained in it and set them to null but will this delete it? Im afraid it might set a reference to nothing leaving the data intact in memory.

One way is to implement the Dispose pattern.

Eh, why? Are you going to require that list elements implement IDisposable as well? Otherwise there's no point.

He didn't say what it was a list of. If this is unmanaged resources we're talking about, it's much better to code defensively than to wait for it to come back and bite you. Clearly it's not POD, since he's trying to set them to null -- you can't set a value type to null. That said, adding a trial check like "Node toDispose = _node as IDisposable;" wouldn't be unreasonable.

Quote:There's no iteration needed. As long as all node objects are unreachable from a GC root, they will be collected.

That statement is a little misleading -- you forgot to add the word "eventually" to the end. Remember, when an object is collected could be a very long time after when it is no longer f-reachable; do you really want your linked list of FileStreams holding on forever? Probably not.

In addition, your solution of merely setting the head and tail to null is not one I'm very fond of. An external reference to one of the nodes would still appear to be valid to the GC (and would never get disposed), even though the rest of the list is supposedly "cleared". This is an inconsistent object state and suggests poor design.

You correctly clarify this by saying that it works only if you don't hand out references externally, but what good is a collection class where you can't see the elements? The "linked list" described with that code looks more like a double-ended stack (you can see the top and the bottom but not anything in between).
- k2"Choose a job you love, and you'll never have to work a day in your life." — Confucius"Logic will get you from A to B. Imagination will get you everywhere." — Albert Einstein"Money is the most egalitarian force in society. It confers power on whoever holds it." — Roger Starr{General Programming Forum FAQ} | {Blog/Journal} | {[email=kkaitan at gmail dot com]e-mail me[/email]} | {excellent webhosting}
Quote:Original post by kSquared
He didn't say what it was a list of.

A fairly reasonable assumption would be that it is a list of either Object or T.
Quote:
If this is unmanaged resources we're talking about, it's much better to code defensively than to wait for it to come back and bite you. Clearly it's not POD, since he's trying to set them to null -- you can't set a value type to null. That said, adding a trial check like "Node toDispose = _node as IDisposable;" wouldn't be unreasonable.

Do you really think the standard containers do this? They don't, because of the cost. If you want to dispose the elements of a list, stack or whatever, you need to do your own iteration and IDispose()'ing, prior to .Clear()'ing the list.

Quote:
Quote:There's no iteration needed. As long as all node objects are unreachable from a GC root, they will be collected.

That statement is a little misleading -- you forgot to add the word "eventually" to the end. Remember, when an object is collected could be a very long time after when it is no longer f-reachable; do you really want your linked list of FileStreams holding on forever? Probably not.

See above.

Quote:}
In addition, your solution of merely setting the head and tail to null is not one I'm very fond of.

That's really too bad, since it's pretty much the only valid idiom in this case.
Quote:
An external reference to one of the nodes would still appear to be valid to the GC (and would never get disposed), even though the rest of the list is supposedly "cleared". This is an inconsistent object state and suggests poor design.

How the hell is that *inconsistent*? The 2.0 linked list class works just like that.
Quote:
You correctly clarify this by saying that it works only if you don't hand out references externally, but what good is a collection class where you can't see the elements?

Uh. You don't hand out references to the *node* objects externally. That doesn't mean you can't hand out references to the elements contained by the nodes.
Quote:
The "linked list" described with that code looks more like a double-ended stack (you can see the top and the bottom but not anything in between).

That's the general idea behind a linked list. If you want to go anywhere else, you start from the front or the back (depending on whether it's a doubly or singly linked list). What's the list object supposed to do - keep a reference to every node in an array, so it can be accessed quickly by index...?

--AnkhSVN - A Visual Studio .NET Addin for the Subversion version control system.[Project site] [IRC channel] [Blog]
Sorry if that came out a little angry-sounding. I probably shouldn't post right after waking up from a nap.
--AnkhSVN - A Visual Studio .NET Addin for the Subversion version control system.[Project site] [IRC channel] [Blog]
It got rid of all the nodes but then it went to add a node and had an error after clearing the list.

Though, I have one small question.
~Node()
{
Dispose(false);
}
is this a destructor?

[Edited by - GDKnight on October 24, 2005 5:55:31 PM]
- GDKnight
Quote:Original post by GDKnight

Though, I have one small question.
~Node()
{
Dispose(false);
}
is this a destructor?

Yes.
Quote:
I was taught that destructors don't exist in C#.

They do, but it's usually not a good idea to rely on them. If you add a destructor, the garbage collector will put the object on something called the "finalization queue" when it collects it. This queue is processed by a low-priority system thread, which can take a long time getting to your object. All this means that if your object contains a destructor, it may stay alive a lot longer than if it didn't have one.

Usually, if you need a destructor (to clean up resources owned by your object that really *needs* to be cleaned up), you should also implement the IDisposable interface. This gives any client the opportunity to explicitly call .Dispose() on your object to release said resources. Your implementation of .Dispose() should call GC.SuppressFinalize to prevent the garbage collector from putting your object on the finalizer queue.

Google for "IDisposable pattern".
--AnkhSVN - A Visual Studio .NET Addin for the Subversion version control system.[Project site] [IRC channel] [Blog]
Solved.
- GDKnight

This topic is closed to new replies.

Advertisement