arrays = pointers?

Z

Zytan

I know there are no pointers in C#, but if you do:
a = b;
and a and b are both arrays, they now both point to the same memory
(changing one changes the other). So, it makes them seem like
pointers.

Can someone please explain why? thanks.

Zytan
 
?

=?ISO-8859-1?Q?Arne_Vajh=F8j?=

Zytan said:
I know there are no pointers in C#, but if you do:
a = b;
and a and b are both arrays, they now both point to the same memory
(changing one changes the other). So, it makes them seem like
pointers.

Can someone please explain why? thanks.

It is a reference, which indeed is very similar to a
C/C++ pointer in some aspects.

But you can not do pointer manipulation with it.

Arne

PS: You do have pointers in C# in unsafe mode.
 
Z

Zytan

It is a reference, which indeed is very similar to a
C/C++ pointer in some aspects.

But you can not do pointer manipulation with it.

Arne

PS: You do have pointers in C# in unsafe mode.

Ok. thanks.

Ok, i just did some testing, and when you pass an array into a
function, regardless if it is ref or not, when the function changes
the array's contents, they are still changed when the function
returns. So, they are like pointers.

Zytan
 
B

Bruce Wood

Ok. thanks.

Ok, i just did some testing, and when you pass an array into a
function, regardless if it is ref or not, when the function changes
the array's contents, they are still changed when the function
returns. So, they are like pointers.

Zytan

Yes, they are. I think of them as pointers, because that's a familiar
idiom for me.

Howver, as Arne pointed out, you can't do pointer arithmetic with
them, and, although you'll never notice it, unlike pointers references
can change at any moment as the Garbage Collector compacts the heap
and moves objects around. As I said, though, you won't notice, because
the reference will always refer to the same object instance, even if
it doesn't always point to the same place in memory.
 
Z

Zytan

Yes, they are. I think of them as pointers, because that's a familiar
idiom for me.

Howver, as Arne pointed out, you can't do pointer arithmetic with
them, and, although you'll never notice it, unlike pointers references
can change at any moment as the Garbage Collector compacts the heap
and moves objects around. As I said, though, you won't notice, because
the reference will always refer to the same object instance, even if
it doesn't always point to the same place in memory.

Bruce,

Thanks for being so clear. I understand just what you're saying.

They are like pointers, but you can't think of it as an actual memory
addresses, since C# doesn't give you that kind of access, for good
reason -- since the GC moves things around on you, as you say, and
this means pointer arithmetic is no good. Also, since it's not really
a pointer, you never need to use ptr-> or *ptr. you always use ptr.
(ptr being an incorrect abbr. here, since it's not a pointer).

So, it's like a pointer. But, it's really a reference.

I just did a test and found that a class that has a private array, if
it passes this out in a property, the caller has the 'pointer' and
thus can change the contents of the private array. (I guess you'd
have to make a copy to pass back in this case.) So, in this case it
acts like a pointer in C, so it's a nice way to think of them, but it
is not a direct analogy. Got it.

So, they are called 'references'? Is this the proper term?

Zytan
 
T

Tom Leylan

Hi Zytan:
They are like pointers, but you can't think of it as an actual memory
addresses, since C# doesn't give you that kind of access, for good
reason -- since the GC moves things around on you, as you say, and
this means pointer arithmetic is no good. Also, since it's not really
a pointer, you never need to use ptr-> or *ptr. you always use ptr.
(ptr being an incorrect abbr. here, since it's not a pointer).

So, it's like a pointer. But, it's really a reference.

A pointer in C is a reference. It's a reference to an area in memory (as
you know) and the act of getting the value at the address of the pointer is
called "dereferencing".
I just did a test and found that a class that has a private array, if
it passes this out in a property, the caller has the 'pointer' and
thus can change the contents of the private array. (I guess you'd
have to make a copy to pass back in this case.) So, in this case it
acts like a pointer in C, so it's a nice way to think of them, but it
is not a direct analogy. Got it.

So, they are called 'references'? Is this the proper term?

I'd tend to get out of the habit of thinking of C# (and VB) references as
pointers. It could mess you up and they aren't pointers. They are called
references because they are and the term itself is used in other situation,
reference counting, etc. They are an indirect route to a stored value.

If you pass an array or any object as a parameter to another method you
generally pass it by value. This value is a reference to the array and as
such you can change the contents of the array but not the reference itself.
If on the other hand you pass the actual reference to the array the method
has access to the contents as well as to the location that holds the
reference which means it can replace the original array with another one.
Sometimes you want that but often you don't. (See: pass by value; pass by
reference)

Hope this helps.
 
?

=?ISO-8859-1?Q?G=F6ran_Andersson?=

Zytan said:
Bruce,

Thanks for being so clear. I understand just what you're saying.

They are like pointers, but you can't think of it as an actual memory
addresses, since C# doesn't give you that kind of access, for good
reason -- since the GC moves things around on you, as you say, and
this means pointer arithmetic is no good. Also, since it's not really
a pointer, you never need to use ptr-> or *ptr. you always use ptr.
(ptr being an incorrect abbr. here, since it's not a pointer).

So, it's like a pointer. But, it's really a reference.

I just did a test and found that a class that has a private array, if
it passes this out in a property, the caller has the 'pointer' and
thus can change the contents of the private array. (I guess you'd
have to make a copy to pass back in this case.)

Yes, reference types (objects) are never copied automatically. If you
want a copy you have to explicitly create one.

An alternative to creating a copy would be to return a wrapper object
that contains the array but only allows read access to it.
So, in this case it
acts like a pointer in C, so it's a nice way to think of them, but it
is not a direct analogy. Got it.

So, they are called 'references'? Is this the proper term?

Yes. It's the proper term.
 
B

Bruce Wood

Hi Zytan:

Pointers are at arms' length in C# for security reasons, as well. You
can do truly nasty, dirty things with pointer arithmetic and aliasing
(casting) in C. You aren't allowed to do any of that in C# because
it's not verifiably correct, and would be a massive security hole.
(Well, you can, but you have to flag the code as "unsafe", which means
exactly what it sounds like: "security hole".)
A pointer in C is a reference. It's a reference to an area in memory (as
you know) and the act of getting the value at the address of the pointer is
called "dereferencing".



I'd tend to get out of the habit of thinking of C# (and VB) references as
pointers. It could mess you up and they aren't pointers.

Oh, c'mon... they _are_ pointers. They're just pointers that are under
total control of the CLR, not under your control. I, too, come from a
C background, and I had no problem understanding what was going on
with references because I immediately saw them as good ol' pointers.
Hands-off pointers, to be sure, but pointers just the same. And, in
fact, if you could snoop inside the stack frame / heap at runtime,
you'd see... pointers. It's just that in C you can play all sorts of
games with them, and in C# they're so far outside your control that
they're almost invisible, but they _are_ there.
If you pass an array or any object as a parameter to another method you
generally pass it by value. This value is a reference to the array and as
such you can change the contents of the array but not the reference itself.

Absolutely, and the analogy in C is that if you pass a pointer to some
structure then you can modify the contents of the structure, but you
cannot change to which structure the pointer points. In order to do
the latter in C you have to pass a pointer to the pointer. In C# it's
no different: reference types (classes) by default have their
references passed by value, which is to say that the runtime passes a
pointer to them. If you want to change the reference to point to a
different object, then you have to pass the reference type by "ref":
in other words, you have to pass a reference to the reference, or a
pointer to the pointer.

What's really different in C# is the interpretation of what is a
"struct": beware, beware of this one! "struct" in C# is very, very
different from "class". Value type (which includes "structs") are
truly passed by value: the value is pushed on the stack, so the called
method gets a copy of the value. Changes to the value are not
reflected in the caller's argument.
If on the other hand you pass the actual reference to the array the method
has access to the contents as well as to the location that holds the
reference which means it can replace the original array with another one.

Be careful with the wording there! I think you wanted to say, "If on
the other hand you pass the array by reference..." which means using
the "ref" keyword, which means passing a reference to the array by
reference. When I hear "pass a reference to the array," I think of
passing the reference by value, which is the usual case.
 
?

=?ISO-8859-1?Q?G=F6ran_Andersson?=

Tom said:
I'd tend to get out of the habit of thinking of C# (and VB) references as
pointers.

Me too.
It could mess you up and they aren't pointers.

Well, yes and no. :)

Under the hood references _are_ just pointers.

On the other hand, the concept of a reference is not the same as the
concept of a pointer. A reference is actually a much easier concept to
work with.
 
Z

Zytan

A pointer in C is a reference. It's a reference to an area in memory (as
you know) and the act of getting the value at the address of the pointer is
called "dereferencing".

I guess i think of C references as pointers internally. I think of
them as one and the same, so it doesn't make any difference to me.
But, for C#, I'd like to get in-the-know with what the proper
terminology is.
I'd tend to get out of the habit of thinking of C# (and VB) references as
pointers. It could mess you up and they aren't pointers. They are called
references because they are and the term itself is used in other situation,
reference counting, etc. They are an indirect route to a stored value.

yes. They are references in a literal sense of the term, so it all
makes sense. I'll stop using the term 'pointer'.
If you pass an array or any object as a parameter to another method you
generally pass it by value. This value is a reference to the array and as
such you can change the contents of the array but not the reference itself.
If on the other hand you pass the actual reference to the array the method
has access to the contents as well as to the location that holds the
reference which means it can replace the original array with another one.
Sometimes you want that but often you don't. (See: pass by value; pass by
reference)

I understand all of this. Exactly like C++ with a pointer to some
data. This is why probably many people think of C# references as
pointers. Really, they are almost the same thing, but since C#
references can move about, they cannot be pointers. Pointers are more
strict and absolute. So, as long as this is known, i think it is
clear why C# references aren't pointers, although since references are
so similar to pointers in many ways, it helps to know what pointers
can/can't do since it can be applied to references, as you've shown
above.
Hope this helps.

it does, thanks.

Zytan
 
Z

Zytan

Yes, reference types (objects) are never copied automatically. If you
want a copy you have to explicitly create one.

Yes, the reference itself is copied, but not what it references. How
can i can tell what types are reference types or not? I know arrays
would be, from my C background, but how else would i know? Would it
be proper to assume all native types (int, double) are not, and
everything else (objects) are?
An alternative to creating a copy would be to return a wrapper object
that contains the array but only allows read access to it.

Great idea.
Yes. It's the proper term.

Thanks, Göran.

Zytan
 
Z

Zytan

Pointers are at arms' length in C# for security reasons, as well. You
can do truly nasty, dirty things with pointer arithmetic and aliasing
(casting) in C. You aren't allowed to do any of that in C# because
it's not verifiably correct, and would be a massive security hole.
(Well, you can, but you have to flag the code as "unsafe", which means
exactly what it sounds like: "security hole".)

Yes, i was just reading about 'unsafe'. So, you can get access to
pointers, but they don't want you to, because of the demons you can
produce with it.
Oh, c'mon... they _are_ pointers. They're just pointers that are under
total control of the CLR, not under your control. I, too, come from a
C background, and I had no problem understanding what was going on
with references because I immediately saw them as good ol' pointers.
Hands-off pointers, to be sure, but pointers just the same. And, in
fact, if you could snoop inside the stack frame / heap at runtime,
you'd see... pointers. It's just that in C you can play all sorts of
games with them, and in C# they're so far outside your control that
they're almost invisible, but they _are_ there.

Right. Basically, they are pointers.

But if you were to grab a pointer, and store the address it points to,
and later return to use that stored address, in C# you cannot be 100%
sure that it still points to the object it used to. Is that right?
Absolutely, and the analogy in C is that if you pass a pointer to some
structure then you can modify the contents of the structure, but you
cannot change to which structure the pointer points. In order to do
the latter in C you have to pass a pointer to the pointer. In C# it's
no different: reference types (classes) by default have their
references passed by value, which is to say that the runtime passes a
pointer to them. If you want to change the reference to point to a
different object, then you have to pass the reference type by "ref":
in other words, you have to pass a reference to the reference, or a
pointer to the pointer.

Yes, Tom showed an exact analog to C++ pointers (passing by ref or
val) or C (using a pointer to a pointer, to emulare C++'s pass by ref
or val).
What's really different in C# is the interpretation of what is a
"struct": beware, beware of this one! "struct" in C# is very, very
different from "class". Value type (which includes "structs") are
truly passed by value: the value is pushed on the stack, so the called
method gets a copy of the value. Changes to the value are not
reflected in the caller's argument.

Ok, so structs are like native types, that are always passed by
value? And classes are like non-native types that are always passed
by reference? I noticed Petzold touch upon this in the intro to
his .NET Book Zero (available for free):
http://www.charlespetzold.com/dotnet/index.html
so it must be a big deal.
Be careful with the wording there! I think you wanted to say, "If on
the other hand you pass the array by reference..." which means using
the "ref" keyword, which means passing a reference to the array by
reference. When I hear "pass a reference to the array," I think of
passing the reference by value, which is the usual case.

yes, nice catch.

Zytan
 
Z

Zytan

It could mess you up and they aren't pointers.
Well, yes and no. :)

Under the hood references _are_ just pointers.

On the other hand, the concept of a reference is not the same as the
concept of a pointer. A reference is actually a much easier concept to
work with.

yes, good point. thanks.

Zytan
 
J

Jon Skeet [C# MVP]

Zytan said:
Yes, the reference itself is copied, but not what it references. How
can i can tell what types are reference types or not? I know arrays
would be, from my C background, but how else would i know? Would it
be proper to assume all native types (int, double) are not, and
everything else (objects) are?

Not quite. There are other value types - DateTime, GUID etc. Basically,
in MSDN, if the description is of a "struct" that means a value type.
If it's of a "class" that means a reference type.
 
?

=?ISO-8859-1?Q?G=F6ran_Andersson?=

Zytan said:
How
can i can tell what types are reference types or not? I know arrays
would be, from my C background, but how else would i know? Would it
be proper to assume all native types (int, double) are not, and
everything else (objects) are?

Yes, the native types are value types, but not everything else are
reference types.

You can easily see the difference in the documentation. Value types are
listed as structures, for example "Int32 structure" and reference types
are listed as classes, for example "String class".
 
B

Bruce Wood

Yes, i was just reading about 'unsafe'. So, you can get access to
pointers, but they don't want you to, because of the demons you can
produce with it.

Yes, and that's why as soon as your program contains an "unsafe"
section it needs elevated privileges to run that section. The CLR
won't allow any Tom-Dick-or-Harry program from the Web to run unsafe
code (unless you're foolish enough to set up your machine's code-based
security that way).

But if you were to grab a pointer, and store the address it points to,
and later return to use that stored address, in C# you cannot be 100%
sure that it still points to the object it used to. Is that right?

Yes, and that's why C# also provides mechanisms to "pin" objects when
calling across to unmanaged (good ol' Win32) code: while code outside
the CLR is looking at / manipulating managed data, the GC has to be
told not to move that data during compaction or... boom!
Ok, so structs are like native types, that are always passed by
value? And classes are like non-native types that are always passed
by reference? I noticed Petzold touch upon this in the intro to
his .NET Book Zero (available for free):http://www.charlespetzold.com/dotnet/index.html
so it must be a big deal.

It is for ex-C hacks like us. I freely admit that I, too, saw "struct"
and thought, "Oh, a lightweight class." No, it's not. It acts, as you
said, like a native type, which is tremendously useful, but if you
abuse it by trying to create a "light" class then you will suddenly
find your code becoming tortured and incomprehensible.

There are lots of threads here about value versus reference
semantics... I don't really want to hijack this thread with that
discussion. Suffice to say that the distinction _is_ a big deal, but
once you "get it" it's not complicated.
 
B

Ben Voigt

Zytan said:
Yes, i was just reading about 'unsafe'. So, you can get access to
pointers, but they don't want you to, because of the demons you can
produce with it.


Right. Basically, they are pointers.

But if you were to grab a pointer, and store the address it points to,
and later return to use that stored address, in C# you cannot be 100%
sure that it still points to the object it used to. Is that right?

Right. You can get the integral value of a reference using IntPtr... but
there's no typesafe way to make an integer back into a reference (though you
can use an unsafe pointer to do so). Still, you can see the actual
in-memory address, and watch to see how it moves (hint, one easy way to make
it move is pinning it with the GCHandle constructor overload).

As long as you have a reference, C# (actually the CLR) tracks it and keeps
it up-to-date. As soon as you put the address in some other variable, like
an integer, the CLR no longer knows you're using it, so the object can be
moved or deleted. C++/CLI actually has a pointer type (interior_ptr) which
allows pointer arithmetic and automatically follows objects moved by the
CLR.
 
W

Willy Denoyette [MVP]

Ben Voigt said:
As long as you have a reference, C# (actually the CLR) tracks it and keeps it up-to-date.
As soon as you put the address in some other variable, like an integer, the CLR no longer
knows you're using it, so the object can be moved or deleted. C++/CLI actually has a
pointer type (interior_ptr) which allows pointer arithmetic and automatically follows
objects moved by the CLR.

True, but this pointer arithmetic renders the code just as unsafe as the /unsafe pointer
support in C#.

Willy.
 
Z

Zytan

Ok, so structs are like native types, that are always passed by
No, classes are *not* passed by reference. References (to instances of
classes) are passed by value. It's well worth making the distinction.

Right, the reference (pointer) is passed by value, and cannot change,
but what it refers to can change. This is what i *meant* by 'classes
are passed by reference', and i see the difference.
Seehttp://pobox.com/~skeet/csharp/parameters.html

thanks for the link. it links to many other pages, too, and i'll read
them all.

Zytan
 

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