Changing pointors value - A solution : Structure

Got an idea for enhancing PureBasic? New command(s) you'd like to see?
Ollivier
Enthusiast
Enthusiast
Posts: 281
Joined: Mon Jul 23, 2007 8:30 pm
Location: FR

Changing pointors value - A solution : Structure

Post by Ollivier »

When I code this:

Code: Select all

*pointor = allocatememory(4096)

*photoX = procedureLambda(*pointor)
*movieY = procedureLambda(*pointor)
*stringZ = procedureLambda(*pointor)
...procedureLambda fills step by step allocated memory pointed by *pointor.

When this allocated memory is full, there is a big problem cause I want to reallocate memory but the start pointor changed.

Code: Select all

*pointor2 = reallocatememory(8192)
If *pointor = *pointor2
  Debug "I am very happy!"
Else
  Debug "I loose all my pointors cause *PhotoX, *movieY and *StringZ become FALSE!"
EndIf
I try to update pointors.
First time, declaring all my pointors like procedure declarations.

Code: Select all

*PointorsBegin
*photoX
*movieY
*stringZ
*PointorsEnd
Second time, updating pointors values in a For...Next, like that:

Code: Select all

      *NewArea = AllocateMemory(NewSize)
      Shift.L = *NewArea - *OldArea
      For i = @*PointorsBegin + 4 To @*PointeursEnd - 4 Step 4
             PokeL(i, PeekL(i) + Shift)
      Next
But now, I see pointors adress doesn't depend of its place in the source code but depends of... it's name!!! :shock:

I suppose it's alphabetical...

Why does the compiler do it??? Useless...
Last edited by Ollivier on Thu Aug 16, 2007 5:44 pm, edited 1 time in total.
User avatar
tinman
PureBasic Expert
PureBasic Expert
Posts: 1102
Joined: Sat Apr 26, 2003 4:56 pm
Location: Level 5 of Robot Hell
Contact:

Re: Updating any used pointors - Rendez-vous with a big bord

Post by tinman »

Why not? There is nothing to say what order the compiler puts variables in memory, unlike e.g. C.

Variables inside functions, however, are on the stack in the order they are declared (i.e. first is at lowest address).

If you are really bothered about having them in order at a global scope you could create a structure:

Code: Select all

Structure MyPointers
*photoX
*movieY
*stringZ
EndStructure

*pointor = allocatememory(4096)
Define.MyPointers ptrs
ptrs\photoX = procedureLambda(*pointor) 
ptrs\movieY = procedureLambda(*pointor) 
ptrs\stringZ = procedureLambda(*pointor) 

*NewArea = AllocateMemory(NewSize)
Shift.L = *NewArea - *pointor 
For i = OffsetOf(ptrs\photoX) To OffsetOf(ptrs\stringZ) Step 4
    PokeL(i, PeekL(i) + Shift)
Next 
Or use an array of pointers.
If you paint your butt blue and glue the hole shut you just themed your ass but lost the functionality.
(WinXPhSP3 PB5.20b14)
Ollivier
Enthusiast
Enthusiast
Posts: 281
Joined: Mon Jul 23, 2007 8:30 pm
Location: FR

Post by Ollivier »

Yes! :D :D

The structure : very good idea. The solution is elegant!

But I want to keep simplicity of syntax.
(Excuse me: it's french. See then main part)

Code: Select all

; CONVENTION

; Suite=
; Zone mémoire constituée d'une succession de valeurs contigües

; Descripteur=
; >> Quad (LONG * 2) décrivant un ensemble
; >> Contient deux Longs : le type et l'attribut 


; _________________________________________________________________________
; STE | Suite des Types d'Ensemble
; SAE | Suite des Attributs d'Ensemble
; TE  | Table des descripteurs d'Ensembles (Regroupant la STE et la SAE)
; ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯

; _________________________________________________________________________
; CONVENTION DES TYPES DE DESCRIPTEUR
; ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
; ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
; Code type      Attribut
; _________________________________________________________________________
; $00 00 00 00 | Inexistant (libre)
;              |
; $01 00 00 00 | Pointeur vers un descripteur d'ensemble dans la TE
; $01 00 00 01 | Variable de type LONG
; $01 00 00 02 | Variable de type FLOAT
; $01 00 00 03 | Pointeur vers une variable de type STRING (Avec terminal 0)
;              |

; $01 01 00 00 | Pointeur de donnée non définie
; $01 01 00 10 | {Pointeur vers une zone mémoire}
; $01 01 00 12 | Idem constituée de pointeurs de donnée non définie
; $01 01 00 13 | Idem constituée de pointeurs vers la TE
;              | 
; $01 02 00 00 | Pointeur de code non défini
;              |
; $01 03 00 00 | Pointeur non défini
;              |
; ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
#Descript  = $01000000
#VarLong   = $01000001
#VarFloat  = $01000002
#VarString = $01000003

; _________________________________________________________________________
; QED.L | Quantité d'Ensembles Disponibles (64, par défaut)
; *STE  | Adresse de la STE
; *SAE  | Adresse de la SAE
; ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
      
      Global QED.L = 64
      Global SHI.L = QED << 2
      Global *SAE
      Global *STE      
      
Procedure CreerTE()
      *SAE = AllocateMemory(QED << 3)
      *STE = *SAE + SHI
EndProcedure

Procedure ModifTE(NouvelleQED.L)
      *NouvelleSAE = AllocateMemory(NouvelleQED << 3)
      *NouvelleSTE = *NouvelleSAE + (NouvelleQED << 2)
      Shift.L = *NouvelleSAE - *SAE
      For i = @*PointeursDebut + 4 To @*PointeursFin - 4 Step 4
            Debug PeekL(i)
            ;PokeL(i, PeekL(i) + Shift)
      Next
      If NouvelleQED > QED
            CopyMemory(*SAE, *NouvelleSAE, SHI)
            CopyMemory(*STE, *NouvelleSTE, SHI)
      Else
            CopyMemory(*SAE, *NouvelleSAE, NouvelleQED << 2)
            CopyMemory(*STE, *NouvelleSTE, NouvelleQED << 2)
      EndIf
      FreeMemory(*SAE)
      *SAE = *NouvelleSAE
      *STE = *NouvelleSTE
      QED = NouvelleQED
      SHI = QED << 2
EndProcedure

Procedure.L InexistTE()
Recherche:
      ! xor   eax,  eax
      ! mov   edi,  dword [p_STE]
      ! mov   ecx,  dword [v_QED]
      ! cld
      ! repne scasd
      ! jnz   l_introuvable
      ! mov   eax,  edi
      ! sub   eax,  4
      ProcedureReturn
introuvable:
      MessageRequester("TE pleine!", "La TE va passer à " + Str(QED << 1) + " éléments !")
      ModifTE(QED << 1)
      Goto Recherche
EndProcedure

Procedure Reg(*Adr, Type.L, *Var)
      PokeL(*Adr + SHI, Type)
      PokeL(*Adr, PeekL(*Var) )
EndProcedure

Procedure Def(Type.L, *Var)    
      *Adr = InexistTE() - SHI
      Reg(*Adr, Type, *Var)
      ProcedureReturn *Adr
EndProcedure
      
Procedure.L DetType(*Adr)
      Type.L = PeekL(*Adr + SHI)
      ProcedureReturn Type
EndProcedure

Procedure.L DetAttr(*Adr)
      Attr.L = PeekL(*Adr)
      ProcedureReturn Attr
EndProcedure

Procedure DefS(String.S)
      LString.L = Len(String) + 1             ; Calcule la quantité à traiter
      *Ptr = AllocateMemory(LString)          ; Alloue la mémoire correspondante
      *Adr = Def(#VarString, @*Ptr)           ; Définit la chaîne
      CopyMemory(@String, *Ptr, LString)      ; Transfert la chaîne
      ProcedureReturn *Adr                  ; Retourne l'adresse de l'ensemble
EndProcedure

Procedure.S DetS(*Adr)
      *Ptr = PeekL(*Adr)
      LString = MemorySize(*Ptr)
      String.S = Space(LString)
      CopyMemory(*Ptr, @String, LString)
      ProcedureReturn String
EndProcedure
      
Procedure DefF(Float.F)
      *Adr = Def(#VarFloat, @Float)
      ProcedureReturn *Adr
EndProcedure

Procedure.F DetF(*Adr)
      Float.F = PeekF(*Adr)
      ProcedureReturn Float
EndProcedure
      
Procedure DefL(Long.L)
      *Adr = Def(#VarLong, @Long)
      ProcedureReturn *Adr
EndProcedure

Procedure.L DetL(*Adr)
      Long.L = PeekL(*Adr)
      ProcedureReturn Long
EndProcedure
      




;***********************      
      ;MAIN PART
;***********************      
      
      
      CreerTE()

      *x = DefS("Hello")
      *z = DefS("Good bye")
      *y = DefF(29.9)
      *t = DefF(30.1)
      *a = DefL(29)
      *b = DefL(31)
      
      Debug "(" + DetS(*x) + ")"
      Debug "(" + DetS(*z) + ")"
      Debug StrF(DetF(*y) )
      Debug StrF(DetF(*t) )
      Debug PeekL(*a)
      Debug PeekL(*b)

      
Your answer helped me to find an other solution with arrays. A modification who won't reach the 'user' (other programmer really):
add area memory and store the start pointors (no used by user) in an array!

Thanks! Really!
Ollivier
Enthusiast
Enthusiast
Posts: 281
Joined: Mon Jul 23, 2007 8:30 pm
Location: FR

Post by Ollivier »

I become crazy with these arrays!

Finally, it's your first solution : the structures...
User avatar
tinman
PureBasic Expert
PureBasic Expert
Posts: 1102
Joined: Sat Apr 26, 2003 4:56 pm
Location: Level 5 of Robot Hell
Contact:

Post by tinman »

Glad to hear it, although I realised this morning that the code I copied and pasted from your original message will not work. It would need to be something like this to work correctly:

Code: Select all

Structure MyPointers 
*photoX 
*movieY 
*stringZ 
EndStructure 

*pointor = allocatememory(4096) 
Define.MyPointers ptrs 
ptrs\photoX = procedureLambda(*pointor) 
ptrs\movieY = procedureLambda(*pointor) 
ptrs\stringZ = procedureLambda(*pointor) 

*NewArea = AllocateMemory(NewSize) 
Shift.L = *NewArea - *pointor 
For i = @ptrs\photoX To @ptrs\stringZ Step 4 
    PokeL(i, PeekL(i) + Shift) 
Next
If you paint your butt blue and glue the hole shut you just themed your ass but lost the functionality.
(WinXPhSP3 PB5.20b14)
Ollivier
Enthusiast
Enthusiast
Posts: 281
Joined: Mon Jul 23, 2007 8:30 pm
Location: FR

Post by Ollivier »

After reflexion, I can't use structures.

Replacing expression:

Code: Select all

*group
by:

Code: Select all

p\group
It's not the real problem. Your solution is very good. Your code shifting automatically values of each pointor is good too. (Excuse me, I didn't see error in your first code, cause I hadn't the time to check it) But adding structure header for each new pointor, it's too!

I think my memory architecture choice will be using fragmented memory. This technic will be allow me to keep my pointors. If I meet new problems, your solution will be used. Cause your last code is exact.

Thank you!
Post Reply