SnowyDog wrote: Sun Apr 06, 2025 3:16 pm
I just want to understand how I have managed to misunderstand this fundamental concept! I have been using PB for some time and this is the first time I've run into this.
It seems to me that there is nothing in the PB help or online docs that indicates that a pointer can't simply be passed by reference to a procedure without a structure. Also, I can find no explanation that the built-in .integer struct that mk-soft demonstrated, exists.
Where should I be looking (in available documentation) to find this information, please?
You do appear to have some very basic misunderstandings for the advance topic of pointers.
I've listed a few concepts below (that's all there really is). The Help file could use some more examples but most of the information is in the help file. The additional things could use some mentioning in the help file. They are known by advanced users and have been discussed in the forum but aren't really present in the help file.
The information regarding pointers is:
- Pointers' names include the '*' prefix at all times except within structures. With structures the prefix is only present in the definition of the structure. See Pointers and Memory Addresses. See Pointers and Memory Addresses; Structures
- Pointers point to memory addresses. Pointers contain Integer values, the same as Integers. This means whenever the value of a pointer is needed, this value could be held by an Integer variable. Neither Integers nor unstructured Pointers can be dereferenced directly (they can be for simple types with the Peek and Poke memory functions).
See Pointers and Memory Addresses; Memory Library.
- Pointers can be structured (declared with a structured type) and dereferenced
See Pointers and Memory Addresses; Structures
- Additional topic -- pointer math (increment or decrement of pointer) with structured pointers is done by memory bytes and not multiples of structure size being referenced, no Help file reference?.
- Additional topic -- comparisons between pointer values (i.e. *pointer_1>*pointer_2) should be made in light of fact that pointers are signed values even though they reference unsigned memory addresses, no Help file reference?.
- Additional topic -- Predefined structures exist for convenience in dereferencing basic variable types, no Help file reference. They could also be defined as needed, just like any other structure.
- Additional topic -- Dereferencing a pointer to a static array of length 0, no Help file reference.
To show some additional methods for accomplishing the issues of your original post I've extended your code example to include three more methods. A pointer can be passed by reference to a procedure without a structure. The problems were with how you did it. I cover a few different ways in the code below.
Code: Select all
EnableExplicit
#StartSize=1024
#NewSize=1048576
Structure MEMBLK
*MemPtr
EndStructure
Declare Main()
Declare.i SubFunc1a(*MemPtr, newSize)
Declare.i SubFunc1b(MemPtr, newSize)
Declare.i SubFunc1c(*PtrMemPtr, newSize)
Declare SubFunc2a(*MemBlk.MEMBLK, newSize)
Declare SubFunc2b(*MemPtr.Integer, newSize)
Main()
End
Macro EvaluateReAllocate(_IntResultVar_, _IntUpdateMemVar_)
If _IntResultVar_ = 0
Debug "Memory reallocation failed"
Else
_IntUpdateMemVar_ = _IntResultVar_
_IntResultVar_ = 0 ;value no longer needed
EndIf
EndMacro
Macro DebugBefore(_varMemoryRefStr_, _varMemoryRefVar_)
Debug "Before:" + #CRLF$ + " " + _varMemoryRefStr_ + " = 0x" + Hex(_varMemoryRefVar_, #PB_Quad) + #CRLF$ +
" MemorySize(" + _varMemoryRefStr_ + ") =" + Str(MemorySize(_varMemoryRefVar_))
EndMacro
Macro DebugAfter(_varMemoryRefStr_, _varMemoryRefVar_)
Debug " After:" + #CRLF$ + " " + _varMemoryRefStr_ + " = 0x" + Hex(_varMemoryRefVar_, #PB_Quad) + #CRLF$ +
" MemorySize(" + _varMemoryRefStr_ + ") =" + Str(MemorySize(_varMemoryRefVar_)) + #CRLF$
EndMacro
Procedure Main()
Protected *result
; Pointer not within structure
Debug "Pointer not within structure"
Protected *MemPtr
*MemPtr = AllocateMemory(#StartSize)
DebugBefore("*MemPtr",*MemPtr)
*result = SubFunc1a(*MemPtr, #NewSize)
EvaluateReAllocate(*result, *MemPtr)
DebugAfter("*MemPtr",*MemPtr)
FreeMemory(*MemPtr): *MemPtr = 0
; Integer variable containing address not within structure
Debug "Integer variable containing address not within structure"
*MemPtr = AllocateMemory(#StartSize)
DebugBefore("*MemPtr",*MemPtr)
*result = SubFunc1b(*MemPtr, #NewSize)
EvaluateReAllocate(*result, *MemPtr)
DebugAfter("*MemPtr",*MemPtr)
FreeMemory(*MemPtr): *MemPtr = 0
; Pointer to a Pointer or Integer not within a structure
Debug "Pointer to a Pointer or Integer not within a structure"
*MemPtr = AllocateMemory(#StartSize)
DebugBefore("*MemPtr",*MemPtr)
*result = SubFunc1c(@*MemPtr, #NewSize)
EvaluateReAllocate(*result, *MemPtr)
DebugAfter("*MemPtr",*MemPtr)
FreeMemory(*MemPtr): *MemPtr = 0
; Pointer within custom structure
Debug "Pointer within structure"
Protected *MemBlk.MEMBLK
*MemBlk = AllocateStructure(MEMBLK)
*MemBlk\MemPtr = AllocateMemory(#StartSize)
DebugBefore("*MemBlk\MemPtr",*MemBlk\MemPtr)
SubFunc2a(*MemBlk, #NewSize)
DebugAfter("*MemBlk\MemPtr",*MemBlk\MemPtr)
FreeMemory(*MemBlk\MemPtr): *MemBlk\MemPtr = 0
FreeStructure(*MemBlk): *MemBlk = 0
; Pointer to Integer dereferenced with predefined structure
Debug "Pointer to Integer dereferenced with predefined structure"
*MemBlk = AllocateStructure(MEMBLK)
*MemBlk\MemPtr = AllocateMemory(#StartSize)
DebugBefore("*MemBlk\MemPtr",*MemBlk\MemPtr)
SubFunc2b(*MemBlk\MemPtr, #NewSize)
DebugAfter("*MemBlk\MemPtr",*MemBlk\MemPtr)
FreeMemory(*MemBlk\MemPtr): *MemBlk\MemPtr = 0
EndProcedure
; Pointer not within structure, returns value of ReAllocateMemory() attempt
Procedure.i SubFunc1a(*MemPtr, newSize)
ProcedureReturn ReAllocateMemory(*MemPtr, newSize)
EndProcedure
; Integer variable containing address not within structure, returns value of ReAllocateMemory() attempt
Procedure.i SubFunc1b(MemPtr, newSize)
ProcedureReturn ReAllocateMemory(MemPtr, newSize)
EndProcedure
; Pointer to a Pointer or Integer not within a structure, returns value of ReAllocateMemory() attempt
Procedure.i SubFunc1c(*PtrMemPtr, newSize)
ProcedureReturn ReAllocateMemory(PeekI(*PtrMemPtr), newSize)
EndProcedure
; Pointer within custom structure
Procedure SubFunc2a(*MemBlk.MEMBLK, newSize)
Protected *result
*result = ReAllocateMemory(*MemBlk\MemPtr, newSize)
EvaluateReAllocate(*result, *MemBlk\MemPtr)
EndProcedure
; Pointer to Integer dereferenced with predefined structure
Procedure SubFunc2b(*MemPtr.Integer, newSize)
Protected *result
*result = ReAllocateMemory(*MemPtr\i, newSize)
EvaluateReAllocate(*result, *MemPtr\i)
EndProcedure[/code]