April 28, 2024, 01:56:25 PM

News:

Own IWBasic 2.x ? -----> Get your free upgrade to 3.x now.........


Passing pointers and Subroutines

Started by LarryMc, April 21, 2007, 09:33:10 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

LarryMc

According to the documentation strings and pointers are passed to subroutines BYREF.
And since they are passed that way the subroutine can change the value of the original variable.

Below are 2 subroutines.
One with pointers as parameters and the other with strings.

Both are passed 2 parameters with the 2nd parameter being initialized to a null.
The subroutines change the 2nd value.

The string function (test2) works as expected.

The pointer function (test) doesn't.

I know that pointers are different but I don't know how to fix this.

Larry

openconsole

pointer inp, outp
string ins,outs
inp=0:outp=0
ins="":outs=""
int k

'pointer test
inp = NEW(INT,1)
k=test(inp, outp)
print k
print "inp ",inp
print "outp ",outp

'string test
ins = "working"
k=test2(ins, outs)
print k
print "ins ",ins
print "outs ",outs

print " Any key to end"
do:until inkey$<>""
closeconsole

sub test(inptr as pointer, outptr as pointer),int
pointer ptemp
ptemp = NEW(INT,1)
outptr = ptemp
print "inside sub ",outptr
return 55
endsub

sub test2(ins as string, outs as string),int
string temp
stemp = "testing"
outs = stemp
print "inside sub ",outs
return 99
endsub


LarryMc
Larry McCaughn :)
Author of IWB+, Custom Button Designer library, Custom Chart Designer library, Snippet Manager, IWGrid control library, LM_Image control library

Parker

What it means is passing a variable as a pointer passes it by reference. So you can change the contents by dereferencing, but you still have to use the byref keyword to pass a reference to a pointer.

LarryMc

can you change my sample code above to make it work?

thanks
Larry
LarryMc
Larry McCaughn :)
Author of IWB+, Custom Button Designer library, Custom Chart Designer library, Snippet Manager, IWGrid control library, LM_Image control library

REDEBOLT

Larry,

In subroutine "test," you are creating a new integer object referenced by ptemp.  You then assign this pointer to "outptr" which gives the calling code a pointer to an integer.  But herein lies the rub.  When you exit "test" you abandon the local pointer ptemp and the int becomes an orphan and dies.  Furthermore, you haven't deleted any of your NEW objects before the program ends, thus causing a memory leak.

I'm still trying to make the program work.   :)
Regards,
Bob

REDEBOLT

In trying to determine the intent of subroutine "test" I think you are trying to create a new integer and pass its address back to the caller.  You can't do this, because the new object is local and expires when the sub is exited.  So, I think you have to create the integer in your calling code and then "test" can modify it.

So, here goes"
openconsole

pointer inp, outp
string ins,outs
inp=0:outp=0
ins="":outs=""
int k

'======================================================
'pointer test
inp = NEW(INT,1)
outp = NEW(INT,1) ' Create the new int here.
*<INT>inp = 4
*<INT>outp = 3
k=test(inp, outp)
print k
print "inp ",*<INT>inp
print "outp ",*<INT>outp
'======================================================

'string test
ins = "working"
k=test2(ins, outs)
print k
print "ins ",ins
print "outs ",outs

delete inp
delete outp
print " Any key to end"
do:until inkey$<>""
closeconsole

'======================================================
sub test(inptr as pointer, outptr as pointer),int
*<INT>outptr += *<INT>inptr
print "inside sub ",*<INT>outptr
return 55
endsub
'======================================================

sub test2(ins as string, outs as string),int
string stemp
stemp = "testing"
outs = stemp
print "inside sub ",outs
return 99
endsub

Regards,
Bob

LarryMc

April 21, 2007, 04:59:42 PM #5 Last Edit: April 21, 2007, 05:03:57 PM by Larry McCaughn
Bob
I think I didn't give enough information and that my example is probably mis-leading.

My current sub looks like this:
sub mysub(inp as pointer),pointer
  blah......
  blah......
return inp
endsub

I don't know before hand if the inp pointer is for an int,udt, or what.

Right now I call the sub like thus:
def pTemp as pointer
ptemp = mysub(new(int,1))
*<INT>ptemp = 99
print "ptemp ",*<INT>ptemp

That, in and of itself, doesn't make sense but it works that way because of other things in the blah...blah... of the sub.

Since the sub returns a pointer I am not able to return an error code from the sub.

I want the sub to look like this:
sub mysub(inp as pointer, outp as pointer),int
  def err_code as int
  err_code = 0
  blah......
  err_code = 2
  blah......
  outp=inp
return err_code
endsub

And call the sub this way:
def pTemp as pointer
if  mysub(new(int,1),pTemp) <> 0
   print "have an error"
else
*<INT>ptemp = 99
  print "ptemp ",*<INT>ptemp
endif
LarryMc
Larry McCaughn :)
Author of IWB+, Custom Button Designer library, Custom Chart Designer library, Snippet Manager, IWGrid control library, LM_Image control library

REDEBOLT

This doesn't look like your previous code.  Could you post the complete program?  I would need to see your code in context.

???
Regards,
Bob

LarryMc

Bob
The 1st code was just a demo.  If I could do it with my sample I can do it with my real code.
But, since you're willling to help and can't see with the sample here is ONE of my subs I want to convert.
SUB LList::AddHead(pData as POINTER),POINTER
   ErrCode=0
   POINTER pTemp
   IF m_p_start <> 0
      pTemp = #<LINKEDLIST>m_p_start.pNext
      #<LINKEDLIST>m_p_start.pNext = NEW(LINKEDLIST,1)

      m_p_current_pos = #<LINKEDLIST>m_p_start.pNext

      IF pTemp <> NULL
         #<LINKEDLIST>m_p_start.#<LINKEDLIST>pNext.pNext = pTemp
         #<LINKEDLIST>pTemp.pPrev = #<LINKEDLIST>m_p_start.pNext
      ENDIF
      #<LINKEDLIST>m_p_start.#<LINKEDLIST>pNext.pPrev = m_p_start
      #<LINKEDLIST>m_p_start.#<LINKEDLIST>pNext.pData = pData
   else
      ErrCode = 8
   ENDIF
   RETURN pData
ENDSUB

Larry
LarryMc
Larry McCaughn :)
Author of IWB+, Custom Button Designer library, Custom Chart Designer library, Snippet Manager, IWGrid control library, LM_Image control library

LarryMc

Bob,
I found something that works and may fit my needs.
If I declare a memory variable as a pointer then I can set the memory variable to the passed in inp pointer and then after coming out of the subroutine the memory variable will contain the pointer to the data.

Just a thought.
LarryMc
Larry McCaughn :)
Author of IWB+, Custom Button Designer library, Custom Chart Designer library, Snippet Manager, IWGrid control library, LM_Image control library

REDEBOLT

Regards,
Bob