Pointers In VS2005

  • Thread starter Thread starter gnassar
  • Start date Start date
G

gnassar

I've been trying to learn dotnet myself though a bit of a basterdized
know-how of dotnet 2003 and previous straight unix C++ programming.
For some reason I have been able to get most of the mechanics down
quickly but there's something that's been eluding me.

I'm used to:

XmlDocument *xmld1p;
xmld1p = 0;

if (xmldp == 0){
....
}

This is all find and good (assuming I didn't make any minor spelling
mistakes here) in versions of VS prior to 2005. I understand that the
new operator is ^ for managed resources but can I make a pointer of an
object anymore?

I know I need to do:

XmlDocument^ J = new XmlDocument();
Thats fine. but can I make a pointer to a managed resource anymore or
no?

So I guess can I do:
(XmlDocument^) *J;
J = 0;

(That brings errors)
How would I do that?
 
I know I need to do:

XmlDocument^ J = new XmlDocument();
Thats fine.

XmlDocument^ J = gcnew XmlDocument;

but can I make a pointer to a managed resource anymore or
no?

So I guess can I do:
(XmlDocument^) *J;
J = 0;

You can not do it that way. A .NET handle is not a real memory address.
In a managed environment the garbage collector is free to move objects
around in the memory. There is a very real possibility that an object's
address changes during the lifetime of the application, therefore you're
not supposed to make pointers to them.

We all know that sometimes it's inevitable to use pointers, especially
when a managed object must be passed to an unmanaged routine. For this
reason it's possible to lock a managed handle for a brief period of
time, using the pin_ptr syntax:

pin_ptr<MyClass> locked_class(class);

This ensures that the locked object is not moved around, nor is it
garbage collected. You're supposed to release this lock as soon as
possible. A pin_ptr can be treated as an unmanaged pointer, and passed
to unmanaged code.

If you don't call unmanaged routines, you don't need to worry about
pinning. Chances are that you can solve your problem with references. It
is possible to create a reference to a handle:

XmlDocument ^ %

This is analogous to the native

NativeClass * &

syntax. For example:

void Function(XmlDocument^ % result)
{
result = gcnew XmlDocument;
}

So instead of getting a pointer to a handle, you grab a reference to it.

And finally, C++ (and I think C# too) has the concept of tracking
pointer. It has the syntax of interior_ptr<T>. It was mainly invented to
iterate through an array. For example:

array<int>^ buff = gcnew array<int>(100);
interior_ptr<int> p = & buff[0];
int count = buff->Length;
while(count--)
*p = 0;

I do image processing, and I found that the interior_ptr syntax
generates much faster code than the array syntax (such as buff[index]).

interior_ptr doesn't lock the array. If the garbage collector has to
move it around, it simply updates all interior_ptr instances for you
automatically. That means interior_ptr probably has a slight overhead,
and a restriction that it can't be a member of a class (you have to
create it on the stack).

This is entirely different from unmanaged pointers. In a native
application, you can not move an object in the memory, because there's
no easy mechanism for updating every pointer referencing an object.

Tom
 
Tamas said:
array<int>^ buff = gcnew array<int>(100);
interior_ptr<int> p = & buff[0];
int count = buff->Length;
while(count--)
*p = 0;

Oops, I meant

while(count--)
*p++ = 0;

And this is not necessarily the most efficient way to fill an array. I
just wanted to demonstrate the syntax.

Tom
 
Back
Top