newbie question about data persistence

P

Peter Webb

Sorry about the stupid newbie questions, but some things aren't very well
explained in the doco ... at least that I can find.

I do something in my code that works just fine, trouble is I don't know why.
Here is is ..

namespace WindowsApplication1
{
public partial class Form1 : Form
{
static List<foo> foocollection;
..
..
..


}

private void Add_new_foo ()
{ foo foonew =new foo();
foocollection.Add(foonew);
}


Now when I call Add_new_foo, it creates foonew and adds it to foocollection,
as I want it to.

However, as I understand it this is just an object reference to foonew in
foocollection. But foonew only exists during Add_new_foo - its created on
the stack. Why doesn't it disappear when we exit Add_new_foo, and cause the
reference to foonew in foocollection to reference a deleted object? Is the
garbage collector/compiler/something clever enough to know there is a
reference to it in foocollection, and hence keep a persistent copy?

As I say, the code works, and operates how I want it to, but I don't
understand why.

Can anybody help explain this to me?
 
M

Marc Gravell

Assuming "foo" is a class (not a struct) the object/instance is a
reference-type and created on the heap, which is why it lives. The
variable (pointer), however, is essentially a value-type and lives (in
this case) on the stack, but we don't care about the variable itself
if we have shared the reference with somebody.

The first part of the following explains the difference:
http://www.pobox.com/~skeet/csharp/parameters.html

(the second part explains pass-by-value and pass-by-reference, which
is a different concept often confused with this)

Marc
 
P

Peter Duniho

Sorry about the stupid newbie questions, but some things aren't very
well explained in the doco ... at least that I can find.

You should look at the specific documentation on MSDN for the memory
management and garbage collection topics. I think they cover the
basics pretty well.
[...]
However, as I understand it this is just an object reference to foonew
in foocollection. But foonew only exists during Add_new_foo - its
created on the stack. Why doesn't it disappear when we exit
Add_new_foo, and cause the reference to foonew in foocollection to
reference a deleted object? Is the garbage collector/compiler/something
clever enough to know there is a reference to it in foocollection, and
hence keep a persistent copy?

In addition to what Marc wrote, yes...the garbage collector is "clever
enough". It starts with "root" variables (statics and locals), but
it's also aware of what a type contains. It doesn't just look at the
first layer of data; it can follow the chain of references all the way
down.

So you've got a collection, and that collection contains a reference to
the object you created. The GC can look at the collection and know
that it contains that reference, and since the object is thus
reachable, it won't be collected.

Pete
 
P

Peter Webb

So you've got a collection, and that collection contains a reference to
the object you created. The GC can look at the collection and know that
it contains that reference, and since the object is thus reachable, it
won't be collected.

Pete

Thanks. I have a related question, if that's OK. This one is really, really
stupid.

I use the List<> type extensively in my code, basically because I don't know
how to make arrays "persistent".

Certainly, I can make an array

foo [] fooarray = new foo[10];

But the scope of this is only the method in which it is defined.

My code (like everybody else's, I assume) has plenty of data that I want to
keep in arrays that are accessible by many methods. Because I don't know how
to do this, I have resorted to Static List<> types which I define inside
Form1. I simply don't know how to construct a regular array foo[10] that has
a scope wider than the method in which it was created.

Sorry about this, but now having created my 20th or so List<> when all I
really wanted a regular array - and having spent considerable time trying to
work it out for myself - could somebody please put me out of my misery?
 
M

Marc Gravell

Arrays and lists are both reference types, but actually I suspect
you're better off with a List<T> in this case (it will support Add
etc).

Declaring a long-lived array is usually just a case of declaring it as
a field (instance or static) - I'll gloss over the subtleties, but if
you currently have:

class Program {
// static List<T> field
static List<Something> list = new List<Something>();
}

then you can do the same with arrays (assuming you know the size) via:

class Program {
// static T-array field
static Something[] array = new Something[10];
}

If you post your current code somebody can probably explain in terms
closer to your current situation...

Finally - be very wary of too much use of static fields; you can run
into trouble with both garbage-collection and thread-safety. Neither
is fun.

Marc
 
P

Peter Webb

Thankyou, thankyou, thankyou.

I should admit I am doing this just for fun, but I really appreciate the
help. I have found this whole thing intensely interesting. I actually have
post-grad in Computer Science, but object oriented programming wasn't on the
syllabus 30 years ago. Now, 30 years later, there is a whole different
paradigm for programming that I knew existed but never explored.

I've probably now written about a 1,000 lines of C# code, but haven't used
an array yet. So many things in an object model work better Lists and other
data structures; a month ago I wouldn't have believed that you could write
more than ten lines of code which does something useful without an array.

I am so pleased I came across C# Express Edition. I originally just wanted
to do some maths coding, and I asked in sci.math if anybody could recommend
a programming environment for Windows, easy to install, and preferably with
an IDE. I got a few recommendations for installing a Linux emulator and gcc,
which I did, but boy was that cumbersome if you know nothing about Linux. Of
the half dozen responses in sci.math, not one of them mentioned C# EE. I
only heard about it when I asked a programmer at work. This would have to be
the best free thing I have ever got. I must have said in presentations about
a 100 times "Microsoft knows how to look after its developer community", and
now I really believe it.
 
L

Lew

Peter said:
So you've got a collection, and that collection contains a reference
to the object you created. The GC can look at the collection and know
that it contains that reference, and since the object is thus
reachable, it won't be collected.

Pete

Thanks. I have a related question, if that's OK. This one is really,
really stupid.

I use the List<> type extensively in my code, basically because I don't
know how to make arrays "persistent".

Certainly, I can make an array

foo [] fooarray = new foo[10];

But the scope of this is only the method in which it is defined.

The scope of the *variable* is the method. The object itself doesn't have scope.

Assuming a class, as Marc Gravell pointed out, the object lives on the heap.
It is not a variable, it does not have a lifetime bounded by that of pointers
to it.

The 'fooarray' variable is a pointer to the actual array, not the array
itself. Just because one pointer goes out of scope doesn't mean that another
pointer can't point to the same object.

So the way to reach an object outside the scope of a particular block is to
assign a reference to the object to a variable with a wider scope.
 
M

Marc Gravell

I'm glad you have found C# rewarding.
I originally just wanted to do some maths coding

I can't believe I'm saying this, but if you are interested in math
work, you might also want to have a quick look at F#; this is a .NET
functional programming language similar to "OCaml". Personally I'm a
C# advocate, but you may find it interesting. However, you'd struggle
to find quite as much community support, as its target audience is
smaller (unless you ask John Harrop ;-p). Not also that F# is still at
current a research language (although productization by Microsoft has
been formally anounced).

Again; I'd stick with C#, but it is only fair to make an informed
decision...

Marc
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top