Qbasicnews.com

Full Version: Pointers Yet Again
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Pages: 1 2
Is there an alternative for the following:

Code:
'$Include: "crtdll.bi"
Type test
     numstr As Integer
     strs(0) As String Ptr  ' Make dynamic array
End Type

Dim t1 As test,  teststr() As String

Redim teststr(3) As String

teststr(0) = "Zero"
teststr(1) = "One"
teststr(2) = "Two"
teststr(3) = "Three"

t1.strs = calloc(3, 64) ' Allocate memory for pointer array

'Copy Data into string ptr
MemCpy(t1.strs, @teststr(0), 3*64)

Erase teststr

For i = 0 To 3
     Print *t1.strs(i)
Next

I can success run the following routine without the prog crashing:

For i = 0 To 3
t1.strs(i) = testarr(i)
Print *t1.strs(i)
Next

But MemCpy crashes it. I need to copy the data into the actual pointer array. Any ideas?
you need to allocate space for each string first using some function like SPACE$ or STRING$
Do you have any code to see how that would work in my above example using the ptrs. I thought calloc handled memory allocation already.
sry (it's 4am in the morning) if I get smth wrong, but this works:
Code:
option explicit
'$include: 'win\crtdll.bi'
declare sub       PokeStr     ( byval Dest as any ptr, _
                                byref text as string,  _
                                byval Lenght as integer = -1)
declare function  PeekStr     ( src as byte pointer )  as string

'-----------------------
dim test       as string
dim testptr    as any ptr
test = "This is a test string"
TestPtr=callocate(len(test))
PokeStr(TestPtr, test)
test = ""
test = PeekStr(TestPtr)
print Test
sleep
'-----------------------

sub       PokeStr     ( byval Dest as any ptr, _
                        byref text as string,  _
                        byval Lenght as integer)
   if Lenght = -1 then Lenght = len(text)
   memcpy(Dest, sadd(text), Lenght)
end sub
function  PeekStr     ( src as byte pointer )  as string
   PeekStr = *src
end function
The rest you can easily modify yourself, put a pointer into type, or smth, and use PokeStr & PeekStr for rading/writing strings to memory.

Also dynamic units in TYPE structure as far as I know is a unfixed bug, so don't rely on it mutch. I may be wrong though.
I guess you're right it's a bug. I hope it's implemented though.
FB var-len strings have descriptors as in QB/VB, a "dim s as string" allocates just the descriptor, string data is only (re)allocated when the string is assigned.

To get the real address of a var-len string, SADD() has to be used (as in QB), but yeah, you must allocate the data for it if using a pointer.

Btw, you can create var-len string fields on TYPE's, what isn't allowed in QB -- memory will leak if you don't do say mytype.myvarlenstring = "" at end of procs if mytype is local.
Ok. Now I'm just trying to get dynamic pointer arrays to work. Can you help me with this code.

Code:
' Pointer Arrays
' **************
' Alloc Array
Function AllocPtrArr(elem As Long, bytes As Long) As Any Ptr
    AllocPtrArr = Allocate(elem * bytes)
End Function

Sub PutPtrArr(arr As Any Ptr, item As Any Ptr, elem As Long, numelem As Long, bytes As Long)
    Dim temp() As Any Ptr, CopyMemory As Sub(ByVal pDst As Long, ByVal pSrc As Long, ByVal bytes As Long)
    
    Redim temp(numelem) As Any Ptr
    
  '  CopyMemory = DLLFunc("kernel32.dll", "RTLMoveMemory")
    
  
    ' Fill temp array
    MemCpy(temp(0), arr, numelem * bytes)
    
      Print "Working"
    temp(elem) = item
    
    ' Fill ptr array
    MemCpy(arr, temp(0), numelem * bytes)
    
    Erase temp
    
    Print "Working"
End Sub

Function GetPtrArr(arr As Any Ptr, elem As Long, numelem As Long, bytes As Long) As Any
    Dim temp() As Any Ptr, CopyMemory As Sub(ByVal pDst As Long,ByVal pSrc As Long, ByVal bytes As Long)
    
    Redim temp(numelem) As Any Ptr
    
   ' CopyMemory = DLLFunc("kernel32.dll", "RTLMoveMemory")
    
    ' Fill temp array
    MemCpy(temp(0), arr, numelem * bytes)
    
    If temp(0) Then
        GetPtrArr = temp(elem)
    End If    
            
End Function
What about this:

Code:
' Pointer Array Test

Type test
     numstr(0) As Integer Ptr
     strs(0) As String Ptr   ' Make dynamic array
End Type

Dim t1 As test, teststr() As String * 64

Redim teststr(3) As String * 64

teststr(0) = "Zero"
teststr(1) = "One"
teststr(2) = "Two"
teststr(3) = "Three"

For i = 0 To 3
    t1.numstr(i) = Allocate(4)
    t1.strs(i) = Allocate(64) ' Allocate memory for pointer array
Next

' Copy Data into string ptr
For i = 0 To 3
    *t1.numstr(i) = i * 64
    *t1.strs(i) = teststr(i)
Next

Print "Works"  

Erase teststr

For i = 0 To 3
    Print *t1.numstr(i)
    Print *t1.strs(i)
Next

Do Until Inkey$ <> ""
Loop
That won't work, simpler would be:

Code:
const MAXITEMS = 4

Type test
     strs As string ptr
End Type

    Dim t1 As test
    dim p as string ptr

    Redim teststr(3) As String * 64

    teststr(0) = "Zero"
    teststr(1) = "One"
    teststr(2) = "Two"
    teststr(3) = "Three"

    t1.strs = callocate( len( string ) * MAXITEMS )

    ' Copy Data into string ptr
    p = t1.strs
    For i = 0 To MAXITEMS-1
        *p = teststr(i)                     '' can't do t1.strs[i] while there's no pointer indexing
        p = p + len( string )
    Next

    Print "Works"    

    Erase teststr

    p = t1.strs
    For i = 0 To MAXITEMS-1
        Print *p                            '' same as above
        p = p + len( string )
    Next

    sleep

Btw, version 0.09 will complain about len( STRING ), you will have to wait for the new version to compile the code above ;)

EDIT: it should be Callocate instead of Allocate, or else the string assign could try to free an invalid pointer, as Allocate won't fill the block allocated with 0's.
Thanks. Btw, when will pointer indexing be available?
Pages: 1 2