Return pointer to an array from a function

General FreeBASIC programming questions.
Post Reply
rnbas
Posts: 35
Joined: Jul 22, 2019 18:54

Return pointer to an array from a function

Post by rnbas »

I want a function to create an array and return the pointer to it.
The received pointer should be used to print all items in the array.
I tried:

Code: Select all

function returnPtr() as integer
	dim outarr(...) as double = {10.1,20.2,30.3}
	return @outarr
end function

dim newarr(...) as double = returnPtr

for i as integer = 0 to ubound(newarr) 
	print newarr(i)
next
I did not try it since I do not want to risk my system with code I do not understand.
What is correct code for this purpose?
Thanks for your help.
fxm
Moderator
Posts: 12107
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Return pointer to an array from a function

Post by fxm »

The type "array ptr" does not exist.
Therefore, it is not possible to pass/return an array pointer to/from a procedure.
(referring to your example, only a "double ptr" can be used, so that only one element of the array can be referenced by a pointer and not the entire array)

You can pass (by reference) a raw array to a procedure, but you can not return a raw array from a function.
To return an array created within a function, an example of workaround is to embed the array in a user-defined type (udt) to create a user object:

Code: Select all

type UDTarray
   dim as double arr (any)
end type

function returnArr() as UDTarray
   dim as UDTarray outUDT
   redim outUDT.arr(0 To 2)
   outUDT.arr(0) = 10.1
   outUDT.arr(1) = 20.2
   outUDT.arr(2) = 30.3
   return outUDT
end function

dim as UDTarray newUDT = returnArr()

for i as integer = lbound(newUDT.arr) to ubound(newUDT.arr)
   print i, newUDT.arr(i)
next
D.J.Peters
Posts: 8586
Joined: May 28, 2005 3:28
Contact:

Re: Return pointer to an array from a function

Post by D.J.Peters »

Code: Select all

sub returnArray(newArray() as double)
 static outarr(...) as double = {10.1,20.2,30.3}
 redim newArray(ubound(outarr))
 for i as integer = 0 to ubound(outarr)
   newArray(i)=outarr(I)
 next  
end sub
' main
dim as double newarr(any) 
returnArray(newarr())
for i as integer = 0 to ubound(newarr)
  print newarr(i)
next
sleep
fxm
Moderator
Posts: 12107
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Return pointer to an array from a function

Post by fxm »

In your code, "Static" is useless.
dodicat
Posts: 7983
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: Return pointer to an array from a function

Post by dodicat »

rnbas
The pointer to an array is @array( lbound(array) )

In your case @outarr(0)
To follow your format, try

Code: Select all

 

function returnPtr() as double ptr
   static outarr(...) as double = {10.1,20.2,30.3}
   return @outarr(0)
end function


dim newarr(...) as double = {returnPtr[0],returnPtr[1],returnPtr[2]}

for i as integer = 0 to ubound(newarr)
   print newarr(i)
next
sleep

I use static inside the function to preserve the array contents in memory.
Lost Zergling
Posts: 538
Joined: Dec 02, 2011 22:51
Location: France

Re: Return pointer to an array from a function

Post by Lost Zergling »

What really is an array in FB ? It could be summarized as two data structures and a hidden algorithm. The second structure contains all the elements of the array following each other and the first data structure (called the descriptor) contains technical access information (address of the first and last elements, and especially the description of the dimensions which allows access to the elements via intelligible indices). You can get more information on this topic by searching the forum on "Array Descriptor". So you can get a pointer to any element of the array (and possibly even the descriptor) but not a pointer to the array itself which is not just a data structure but the interpretation of two structures through an algorithm (we could imagine an access via a "procptr", but this implementation is not available, probably to preserve array's performances which seems very correct). However, if you are looking to explore conceptual (not strictly technical) workarounds, I would also recommend you to take a look at LZAE (https://freebasic.net/forum/viewtopic.php?f=8&t=27695) . The characteristics of the array (s) are manipulated via an object which is instantiated using the critical information of the descritptor, then the array is manipulated via this object, but it can also be manipulated as a regular array. This is not exactly or really what you are looking for, nevertheless I hope it maybe a few help.
D.J.Peters
Posts: 8586
Joined: May 28, 2005 3:28
Contact:

Re: Return pointer to an array from a function

Post by D.J.Peters »

fxm wrote:In your code, "Static" is useless.
It shows that DIM isn't the only declare statement for an array !
Of course the array isn't read only name it an unknown bug but not useless :-)

Joshy
Lost Zergling
Posts: 538
Joined: Dec 02, 2011 22:51
Location: France

Re: Return pointer to an array from a function

Post by Lost Zergling »

something like this :

Code: Select all

#Include Once "D:\Basic\lzae_04.bi"
Function returnPtr(ByRef aext As ArrayExtension) as integer
	Static outarr(...) as double = {10.1,20.2,30.3}
	aSet(outarr() , aext)
	Return 1
End Function

Dim i As Integer 
Dim aext As ArrayExtension
returnPtr(aext)

For i=1 to aext.NbSteps
    Print aext.Value
    aext.bStep
Next i
Print aext.Value
sleep
Advantages :
- outarr() can be handled as a native FB array
- Only one dim for outarr, we sure only one array in memory
- Code is pretty easy to use and readable
Drawbacks :
- using libraries
- workaround
- "static" is required (if you replace static by dim it does not works)
Of course, using a function for printing with an array passed byref would be simpler.
fxm
Moderator
Posts: 12107
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Return pointer to an array from a function

Post by fxm »

D.J.Peters wrote:
fxm wrote:In your code, "Static" is useless.
It shows that DIM isn't the only declare statement for an array !
Of course the array isn't read only name it an unknown bug but not useless :-)

Joshy
To be more precise, I meant that it is not worth declaring a global array (with 'Static'), but declare a local array is enough (with 'Dim').
(useless to declare a global array with 'Static')
Lost Zergling
Posts: 538
Joined: Dec 02, 2011 22:51
Location: France

Re: Return pointer to an array from a function

Post by Lost Zergling »

Even though at the technical level in the Globals section, Static means "persistent" (it is rather a scope of duration than mapping). If the array is not copied, it ceases to exist at the end of the returnPtr function. Starting with the principle of creating the array in the function, using only one array and keeping the performance and native access of outarr () I can't see other possible option than Static. For a udt (benefiting from persistence of the instance), the programmer has the hand on this persistence because it stops when destructor is called, but is it possible(*) to erase on demand a variable previously declared Static in another scope (Delete Static outarr ())?
(*) suppose it is not, but I wonder if lzae could be used as a workaround for reusing/accessing the memory place ?..
fxm
Moderator
Posts: 12107
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Return pointer to an array from a function

Post by fxm »

A variant to my previous workaround code:
A single array, dynamic (to be able to free the allocated memory for its elements), within a single static UDT instance defined in a function returning a reference to this instance.

Code: Select all

type UDTarray
   dim as double arr(any)
end type

function returnArr() byref as UDTarray
   static as UDTarray outUDT
   function = outUDT
   #define myOutArray outUDT.arr
   redim myOutArray(0 To 2)
   myOutArray(0) = 10.1
   myOutArray(1) = 20.2
   myOutArray(2) = 30.3
end function

dim byref as UDTarray rtnUDT = returnArr()
#define myRtnArray rtnUDT.arr

print "array elements:"
for i as integer = lbound(myRtnArray) to ubound(myRtnArray)
   print i, myRtnArray(i)
next
print

erase myRtnArray

print "array elements:"
for i as integer = lbound(myRtnArray) to ubound(myRtnArray)
   print i, myRtnArray(i)
next
print

sleep
Lost Zergling
Posts: 538
Joined: Dec 02, 2011 22:51
Location: France

Re: Return pointer to an array from a function

Post by Lost Zergling »

Sounds like a "quirk" !-)

Code: Select all

#Include Once "D:\Basic\lzae_04.bi"
 
Function returnPtr(ByRef aext As ArrayExtension, nB as Integer=2) as integer    
	Static outarr() as double '= {10.1,20.2,30.3}
    Redim Preserve outarr(nB) 
    outarr(0)=10.1 : outarr(1)=20.2 : outarr(2)+=30.3 : 
	aSet(outarr() , aext)
    Return 1
End Function


Dim i As Integer
Dim aext As ArrayExtension
returnPtr(aext,4)


For i=1 to aext.NbSteps
    Print aext.Value
    aext.bStep
Next i
Print aext.Value


returnPtr(aext,4)
For i=1 to aext.NbSteps
    Print aext.Value
    aext.bStep
Next i
Print aext.Value


sleep

Works fine indeed !
Output is :
10.1
20.2
30.3
0
0
Then
10.1
20.2
60.6 => Same array
0
0
dodicat
Posts: 7983
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: Return pointer to an array from a function

Post by dodicat »

You can manipulate from outside by a pointer.
But you are not able to delete the static array.

Code: Select all

 
sub show(byref p as double ptr=0)
    static a(...) as double = {10.1,20.2,30.3}
      p=@a(0)
    for n as ulong=lbound(a) to ubound(a)
    print "a(";n;") ";a(n)
   next
    print
end sub

dim  p as double ptr

show p 'init the pointer

p[0]=1.1
p[1]=2.2
p[2]=3.3

show p

for n as long=0 to 2
    p[n]=rnd
next

show p

print "done"

sleep

The delete seems a bit sluggish?
Lost Zergling
Posts: 538
Joined: Dec 02, 2011 22:51
Location: France

Re: Return pointer to an array from a function

Post by Lost Zergling »

Yes, instead of deleting outside, a redim inside a parallel scope (triggered by a parameter passed to the function) will indicate to the compiler the free space. It is difficult to imagine Dim doing the job just one way.
lzae envisaged evolutions : support for indices on SetCursor(indice, (...) as integer) (not just array element adresses because they suppose an access to the original array), aset and overall : minimal support for c-style arrays idendified by Ptr As New Datatype[xx] (for convergence), and so on (the tool is still in its infancy)
Post Reply