comp.lang.idl-pvwave archive
Messages from Usenet group comp.lang.idl-pvwave, compiled by Paulo Penteado

Home » Public Forums » archive » Re: Pointer Behavior Objects Vs Plain routines?
Show: Today's Messages :: Show Polls :: Message Navigator
E-mail to friend 
Switch to threaded view of this topic Create a new topic Submit Reply
Re: Pointer Behavior Objects Vs Plain routines? [message #32075] Wed, 11 September 2002 08:55 Go to next message
JD Smith is currently offline  JD Smith
Messages: 850
Registered: December 1999
Senior Member
On Wed, 11 Sep 2002 08:17:14 -0700, David Fanning wrote:

> savoie@nsidc.org (savoie@nsidc.org) writes:
>
>> O.k. I'm looking at some pointer weridness. Well, I'm calling it
>> weirdness because I obviously don't understand something that is
>> happening. There are two examples below.
>>
>> The first is just two routines. test: creates a pointer, calls
>> changePtr with a null pointer as an argument; and changePtr: which just
>> assigns a string the the passedPtr. This examples shows that if you
>> pass a pointer to a procedure, assign something to that pointer, you
>> can retrieve it after exit.
>>
>>
>> The rest of the routines are a simple object with a couple of methods,
>> showing exactly the opposite effect. When the object's CHANGEPTR
>> method is called, self.myptr doesn't seem to be able to be changed on
>> return.
>
> The problem here has nothing to do with either pointers or objects. The
> problem is that structure dereferences (I.e., self.myptr) are passed by
> value, whereas passing the pointer itself (I.e., myptr) is passed by
> reference. Procedures can change things that are passed by reference.
> They work on *copies* of things that are passed by value.
>
>
>
This is the problem, but I think it's also instructive to understand why
exactly it's *not* related to pointers, which otherwise shouldn't care
about by-value or by-reference, since they point to an area of global
heap.

In DOIT, you say:

ptrInside = ptr_new('Why can not I change this?')

With this statement, you are *not*, as you might think, changing the value
of the pointer contained in the argument variable `ptrInside' (which
happens to be the same as the `self.myptr' instance variable). You are
changing the value of the `ptrInside' variable itself. You have assigned
it to a new pointer! Had `self.myptr' already had something in it (i.e.
been a "valid" pointer), you could have said:

*ptrInside='Why can not I change this?'

and actually changed the value in `self.myptr'. In your case, the
variable `ptrInside' disappears from the world forever when DOIT returns:
you've just created a memory leak. Note that you can arrange to avoid the
pass-by-value structure problem, with something like:


PRO WEIRD::CHANGEPTR
ptr=self.myptr
self -> doIt, ptr
self.myptr=ptr
END

But this doesn't help: either way you risk a memory leak, since only one
of the two pointers created would still be accessible.

David's suggested method is the way to go.

Good luck,

JD
Re: Pointer Behavior Objects Vs Plain routines? [message #32084 is a reply to message #32075] Wed, 11 September 2002 10:19 Go to previous messageGo to next message
Pavel A. Romashkin is currently offline  Pavel A. Romashkin
Messages: 531
Registered: November 2000
Senior Member
savoie@nsidc.org wrote:
>
> *Morning coffee hits* Aha, but I'm doing is defining what it points to _the
> first time_ with a copy. This changes the copy, making it a valid pointer,
> leaving my original pointer alone. Duh.
>
> But if the pointer is already valid, I should be able to dereference the copy
> and store whatever I want, blissfully ignorant of what it was pointing at
> thanks to the magic of IDL pointers.

Precisely. If passed pointer is not valid, the copy means nothing, too,
and is not returned back to the caller. If it is valid, changing the
copy will change the original. You need no objects to illustrate this.
Make a tiny change to your code:
*******
PRO CHANGEPTR, passedPtr
on_error, 1 ; Needed because will err on null ptr
*passedPtr = 'This is weird?'
END
*******
IDL> a = {a:ptr_new(), b:ptr_new(/alloc)}
IDL> changeptr, a.a
% Unable to dereference NULL pointer: PASSEDPTR.
% Error occurred at: CHANGEPTR 7
% $MAIN$
% Execution halted at: $MAIN$
IDL> changeptr, a.b
IDL> print, *a.a
% Unable to dereference NULL pointer: <POINTER (<NullPointer>)>.
% Execution halted at: $MAIN$
IDL> print, *a.b
This is weird?

Works just as you described.
Cheers,
Pavel
Re: Pointer Behavior Objects Vs Plain routines? [message #32085 is a reply to message #32075] Wed, 11 September 2002 10:19 Go to previous message
David Fanning is currently offline  David Fanning
Messages: 11724
Registered: August 2001
Senior Member
Pavel A. Romashkin (pavel_romashkin@hotmail.com) writes:

> Hey, we'd all like that! But then again, 1/3 more than free in this case
> is roughly $200 per hour or $25 per line of code, right? :-)

I think of giving free advice as something akin to
breathing. If I didn't do it, I'd be playing tennis
even more than I am now. My wife, unfortunately,
feels otherwise. :-(

Cheers,

David

--
David W. Fanning, Ph.D.
Fanning Software Consulting, Inc.
Phone: 970-221-0438, E-mail: david@dfanning.com
Coyote's Guide to IDL Programming: http://www.dfanning.com/
Toll-Free IDL Book Orders: 1-888-461-0155
Re: Pointer Behavior Objects Vs Plain routines? [message #32086 is a reply to message #32075] Wed, 11 September 2002 10:05 Go to previous message
Pavel A. Romashkin is currently offline  Pavel A. Romashkin
Messages: 531
Registered: November 2000
Senior Member
David Fanning wrote:
>
> My pleasure. Did you know you can get service that is twice
> as fast for only a third more per month?

Hey, we'd all like that! But then again, 1/3 more than free in this case
is roughly $200 per hour or $25 per line of code, right? :-)

Cheers,
Pavel
Re: Pointer Behavior Objects Vs Plain routines? [message #32088 is a reply to message #32075] Wed, 11 September 2002 09:37 Go to previous message
David Fanning is currently offline  David Fanning
Messages: 11724
Registered: August 2001
Senior Member
savoie@nsidc.org (savoie@nsidc.org) writes:

>> Procedures can change things that are passed by reference.
>> They work on *copies* of things that are passed by value.
>
> O.k. I'll agree with that, I actually thought it was being passed by value.
> But thought, shouldn't a pointer and a copy of a pointer point to the same
> thing?

Yes, and I'm sure it does. The problem is not that the pointer
doesn't point to the same thing, the problem is that you can't
get the pointer that is pointing to the same thing back to the
calling program! You don't have a passing mechanism in the program
in the way you wrote it.

> *Morning coffee hits* Aha, but I'm doing is defining what it points to _the
> first time_ with a copy. This changes the copy, making it a valid pointer,
> leaving my original pointer alone. Duh.

You must be drinking the Arabian variety. What I'm drinking
isn't strong enough to figure out what this means. :-)

> But if the pointer is already valid, I should be able to dereference the copy
> and store whatever I want, blissfully ignorant of what it was pointing at
> thanks to the magic of IDL pointers.

I *think* this is right, although I'm not convinced I'm
following the logic every step of the way here.

>
>> Since your DOIT method is a self method, you can simple
>> change it like this:
>>
>> PRO WEIRD::DOIT
>> self.myptr = ptr_new('Why can not I change this?')
>> END
>>
>> Then, call it like this:
>>
>> self -> Doit
>
> If Doit didn't have to act on a whole bunch of different internal variables, I
> could do that.
>
>
> But it actually does a bunch of repetitive things and is called
>
> self->DoIt, self.type1internalPointer, 'type1'
> self->DoIt, self.type2internalPointer, 'type2'
> self->DoIt, self.typeNinternalPointer, 'typeN'
>
> for several different types. I could redesign to an array of internal
> pointers and an array of types, but since It's already coded the other way....

Why can't you just pass in the "type" as a parameter? It already
knows about all the pointers. Those are obviously in the self structure.


> I can change this Weird::init function to initialize the pointer, and just
> dereference in the WEIRD::DoIt Function.
>
>
> PRO WEIRD::DOIT, ptrInside
> *ptrInside = 'Look how I can change this?'
> END
>
> ;; Don't forget to make your INIT function , a member function
> FUNCTION WEIRD::INIT
> self.myPtr = ptr_new('0')
> return, 1
> END

If you just want to initialize the pointer (make it valid, but
not pointing to anything in particular), you can do this:

self.myPtr = Ptr_New(/Allocate_Heap)

Now it is a valid pointer (it can be de-referenced) that points to
an undefined variable.

> And hope/trust that IDL is smart enought to not write over the end of the
> memory like C would. I vaguely remember a thread about growable arrays that
> says I can do this. Anyone think this is a /bad thing/? Rather than just inelegant?

As long as you know what you are doing, even bad things
are sometimes useful.

> Thanks again for such a fast answer!

My pleasure. Did you know you can get service that is twice
as fast for only a third more per month?

Cheers,

David

--
David W. Fanning, Ph.D.
Fanning Software Consulting, Inc.
Phone: 970-221-0438, E-mail: david@dfanning.com
Coyote's Guide to IDL Programming: http://www.dfanning.com/
Toll-Free IDL Book Orders: 1-888-461-0155
Re: Pointer Behavior Objects Vs Plain routines? [message #32091 is a reply to message #32075] Wed, 11 September 2002 09:02 Go to previous message
savoie is currently offline  savoie
Messages: 68
Registered: September 1996
Member
David Fanning <david@dfanning.com> writes:

> savoie@nsidc.org (savoie@nsidc.org) writes:
>
>> O.k. I'm looking at some pointer weridness. Well, I'm calling it weirdness
>> because I obviously don't understand something that is happening. There are
>> two examples below.
>> <snip/>
>
> The problem here has nothing to do with either pointers
> or objects. The problem is that structure dereferences
> (I.e., self.myptr) are passed by value, whereas passing
> the pointer itself (I.e., myptr) is passed by reference.
> Procedures can change things that are passed by reference.
> They work on *copies* of things that are passed by value.

O.k. I'll agree with that, I actually thought it was being passed by value.
But thought, shouldn't a pointer and a copy of a pointer point to the same
thing?

*Morning coffee hits* Aha, but I'm doing is defining what it points to _the
first time_ with a copy. This changes the copy, making it a valid pointer,
leaving my original pointer alone. Duh.

But if the pointer is already valid, I should be able to dereference the copy
and store whatever I want, blissfully ignorant of what it was pointing at
thanks to the magic of IDL pointers.

> Since your DOIT method is a self method, you can simple
> change it like this:
>
> PRO WEIRD::DOIT
> self.myptr = ptr_new('Why can not I change this?')
> END
>
> Then, call it like this:
>
> self -> Doit

If Doit didn't have to act on a whole bunch of different internal variables, I
could do that.


But it actually does a bunch of repetitive things and is called

self->DoIt, self.type1internalPointer, 'type1'
self->DoIt, self.type2internalPointer, 'type2'
self->DoIt, self.typeNinternalPointer, 'typeN'

for several different types. I could redesign to an array of internal
pointers and an array of types, but since It's already coded the other way....

I can change this Weird::init function to initialize the pointer, and just
dereference in the WEIRD::DoIt Function.


PRO WEIRD::DOIT, ptrInside
*ptrInside = 'Look how I can change this?'
END

;; Don't forget to make your INIT function , a member function
FUNCTION WEIRD::INIT
self.myPtr = ptr_new('0')
return, 1
END


And hope/trust that IDL is smart enought to not write over the end of the
memory like C would. I vaguely remember a thread about growable arrays that
says I can do this. Anyone think this is a /bad thing/? Rather than just inelegant?


Thanks again for such a fast answer!


Matt Savoie
National Snow and Ice Data Center, Boulder, CO
Re: Pointer Behavior Objects Vs Plain routines? [message #32092 is a reply to message #32075] Wed, 11 September 2002 08:17 Go to previous message
David Fanning is currently offline  David Fanning
Messages: 11724
Registered: August 2001
Senior Member
savoie@nsidc.org (savoie@nsidc.org) writes:

> O.k. I'm looking at some pointer weridness. Well, I'm calling it weirdness
> because I obviously don't understand something that is happening. There are
> two examples below.
>
> The first is just two routines. test: creates a pointer, calls changePtr
> with a null pointer as an argument; and changePtr: which just assigns a
> string the the passedPtr. This examples shows that if you pass a pointer to
> a procedure, assign something to that pointer, you can retrieve it after
> exit.
>
>
> The rest of the routines are a simple object with a couple of methods,
> showing exactly the opposite effect. When the object's CHANGEPTR method is
> called, self.myptr doesn't seem to be able to be changed on return.

The problem here has nothing to do with either pointers
or objects. The problem is that structure dereferences
(I.e., self.myptr) are passed by value, whereas passing
the pointer itself (I.e., myptr) is passed by reference.
Procedures can change things that are passed by reference.
They work on *copies* of things that are passed by value.

Since your DOIT method is a self method, you can simple
change it like this:

PRO WEIRD::DOIT
self.myptr = ptr_new('Why can not I change this?')
END

Then, call it like this:

self -> Doit

Cheers,

David


--
David W. Fanning, Ph.D.
Fanning Software Consulting, Inc.
Phone: 970-221-0438, E-mail: david@dfanning.com
Coyote's Guide to IDL Programming: http://www.dfanning.com/
Toll-Free IDL Book Orders: 1-888-461-0155
  Switch to threaded view of this topic Create a new topic Submit Reply
Previous Topic: Pointer Behavior Objects Vs Plain routines?
Next Topic: Re: having IDL output to another X11 window

-=] Back to Top [=-
[ Syndicate this forum (XML) ] [ RSS ] [ PDF ]

Current Time: Wed Oct 08 19:19:35 PDT 2025

Total time taken to generate the page: 0.00733 seconds