Memptr set-size() = 0 Has No Effect in Method

Posted by Jeff Ledbetter on 19-Feb-2009 12:46

Hopefully this simple example will explain the behavior.

I have a method in a class that returns a memptr of data. The memptr is properly set to the size of my data each time.

However, if I attempt to set-size = 0, the memptr retains the size from the previous call yet get-pointer-value = 0. The only way to truly set the size to 0, is to first do a set-size() = 1!

Has anyone seen this before?

[View:~/cfs-file.ashx/__key/communityserver-discussions-components-files/19/MemptrTest.cls:550:0]

[View:~/cfs-file.ashx/__key/communityserver-discussions-components-files/19/MemptrTestCaller.p:550:0]

All Replies

Posted by Peter Judge on 19-Feb-2009 12:57

Hopefully this simple example will explain the

behavior.

I have a method in a class that returns a memptr of

data. The memptr is properly set to the size of my

data each time.

However, if I attempt to set-size = 0, the memptr

retains the size from the previous call yet

get-pointer-value = 0. The only way to truly set the

size to 0, is to first do a set-size() = 1!

Has anyone seen this before?

You need to return a MEMPTR as a parameter - they don't get cleaned up automatically when they're a return value (this is true of functions, so I'd expect it to be true of methods too).

-- peter

Posted by Tim Kuehn on 19-Feb-2009 13:01

Are you sure the MEMPTR data is being copied from the method to the calling program?

IIRC, using function / method calls to pass newly-allocated memptrs around have some strange issues with them that make doing this problematic.

Posted by Jeff Ledbetter on 19-Feb-2009 13:01

Hi Peter.

Interesting.

In my real-world application, it seems to clean-up ok. It's when I try to clean it up, by using set-size() = 0 that it doesn't clean up.

In real life, this method is inside a singleton that is returning requested data in a memptr. The odd thing is, is that it reuses the same get-pointer-value with every call. Does that make sense?

Posted by Jeff Ledbetter on 19-Feb-2009 13:04

Good question Tim.

It appears to be as the data I expect to be in the memptr is there by the time it gets out to the main called procedure.

Posted by Tim Kuehn on 19-Feb-2009 13:05

if you display a get-pointer-value on the memptr before the method return, and on the calling procedure's memptr after the return, do they point to the same location?

Posted by Peter Judge on 19-Feb-2009 13:06

Hi Peter.

Interesting.

In my real-world application, it seems to clean-up

ok. It's when I try to clean it up, by using

Are you sure of this? If you use the debugger (in OEA or otherwise) you can track the life of MEMPTRs using the dynamic object monitoring functionality.

set-size() = 0 that it doesn't clean up.

In real life, this method is inside a singleton that

is returning requested data in a memptr. The odd

thing is, is that it reuses the same

get-pointer-value with every call. Does that make

sense?

In the sake of full disclosure, my experience on this comes from demo-ware :); I saw this behaviour in the attached file I was using for a demo.

-- peter

Posted by Jeff Ledbetter on 19-Feb-2009 13:13

Tim, I was just checking that. Yes, they do.

Every iteration uses the same memory location. Is that expected?

Posted by Jeff Ledbetter on 19-Feb-2009 13:19

Sooo.. in everyone's expert opinion, what is the "correct" way to get data in a memptr from a method?

1. Return from method:

define var m as memptr.

m = myClass:getData().

2. Return as output parameter:

define var m as memtpr.

myClass:getData(output m).

3. Pass memptr to method :

define var m as memptr

myClass:getData(m).

Thanks.

Posted by Tim Kuehn on 19-Feb-2009 13:24

Honestly, I think this is sufficiently weird and un-documented as to warrant a call to PSC TS.

Tim

(who wishes there was a way to pass pointers around so they could be played with directly as opposed to this confusing "did it pass a pointer, or make a new memory area" thing we've got now)

Posted by Peter Judge on 19-Feb-2009 13:26

Sooo.. in everyone's expert opinion, what is the

"correct" way to get data in a memptr from a method?

1. Return from method:

define var m as memptr.

m = myClass:getData().

2. Return as output parameter:

define var m as memtpr.

myClass:getData(output m).

3. Pass memptr to method :

define var m as memptr

myClass:getData(m).

I would not do #1. I also agree with Tim's comment re. TS.

-- peter

Posted by Jeff Ledbetter on 19-Feb-2009 13:30

Ok, I'll send something to tech support. In the meantime, I will change my code to use an output parameter.

Posted by Jeff Ledbetter on 19-Feb-2009 13:47

"You need to return a MEMPTR as a parameter - they don't get cleaned up automatically when they're a return value (this is true of functions, so I'd expect it to be true of methods too)."

Peter, can you comment on this further. Under what conditions would a memptr ever get "automatically" cleaned up? Why would this happen when used as an output parameter and what is the cleanup that is occurring?

Sorry if these are boneheaded questions, but I don't want leakage.

Posted by Peter Judge on 19-Feb-2009 14:55

Peter, can you comment on this further. Under what

conditions would a memptr ever get "automatically"

cleaned up? Why would this happen when used as an

output parameter and what is the cleanup that is

occurring?

In some circumstances, if you return a handle (a ProDataSet, say) from a function, you can delete the handle before returning it, and the ABL will defer the deletion until control passes back to the caller.

This doesn't happen with memptrs (for right or wrong; your TS call may help clear that up), and so we have a leak. Output params, on the other hand, are - at least for memptrs - a shallow copy and so don't leak.

hth

-- peter

Posted by Tim Kuehn on 02-Mar-2009 07:54

Looks like Jeff found himself a bug:

P142118: "4GL/ABL: SET-SIZE() = 0 fails to set the size of a MEMPTR variable to zero in a class METHOD."

Cause: Bug# OE00181699

This thread is closed