SnowyDog wrote: Mon Apr 07, 2025 9:46 am
I think my initial misunderstanding stems from the fact that in PB, "*" is not treated as an indirection operator as it is in C. Because, if it is, then
makes no sense as you would be dereferencing the pointer twice.
Code: Select all
@*MemPtr ; Like with any other variable this gets the address of the pointer variable itself
'@' is the address-of operator not a dereferencing operator. It returns a memory address. The dereferencing occurs when you use either the Peek library functions on a memory address (held by a pointer for instance) or you use the structure fiele notation with a structured pointer (i.e. *myPointer\field).
As pointers are integers representing memory addresses, surely I can just use an integer variable name for a pointer without the prefix "*".
Which is simpler in my mind, as when I want to dereference I will be reminded to use the @ prefix, rather than making the mistake of thinking that the pointer is automatically dereferenced with "*" like it is in C.
This is true that an integer can accurately hold a memory address the same as a pointer. Again '@' is the address-of operator. '*' is part of the pointer's name and a pointer can be dereferenced if it is declared with a structure and the structure field notation is used. If the structure field notation is not used you are only referring to the memory address held my the pointer itself.
Code: Select all
;contrived code example to demonstrate some use of pointers
EnableExplicit
Structure Test
Name.s
iq.f ;using a float instead of an integer I.Q. just to be difficult and dim witted ;)
EndStructure
Define.Test me, you ;structured variables
Define memAddr.i ;integer, can hold a memory address if needed (better is to use pointer instead)
Define *ptrTest.Test;structured pointer, can be dereferenced by using field notation of structure
Define *ptrMemAddr ;unstructured pointer, can hold a memory address but can be dereferenced
me\Name = "Snowy"
me\iq = 120
memAddr = @me\iq
*ptrMemAddr = @me ;unstructured pointer holds memory address of structured variable
*ptrTest = @you ;structured pointer holds memory address of structured variable
*ptrTest\Name = "Dog" ;interact with dereferenced field location
*ptrTest\iq = PeekF(memAddr) - 25.0 ;dereferencing an address held by an Integer variable using Peek
Debug "me\Name: " + me\Name + ", me\iq: " + Int(me\iq)
Debug "you\Name: " + you\Name + ", you\iq: " + Int(you\iq)
Debug "Memory address of me: " + Hex(@me, #PB_Quad)
Debug "Memory address of you: " + Hex(@you, #PB_Quad)
Debug "Memory address held by *ptrTest: " + Hex(*ptrTest, #PB_Quad)
Debug "Value held by the variable memAddr: " + Hex(memAddr, #PB_Quad)
Debug "Memory address held by *ptrMemAddr: " + Hex(*ptrTest, #PB_Quad)
Debug LSet("", 50, "-")
*ptrTest = *ptrMemAddr ;point to a new memory location
memAddr = @you\iq
;update structure values
*ptrTest\Name = me\Name + you\Name
*ptrTest\iq = me\iq + (PeekF(memAddr) / 5.0)
PokeF(memAddr, 90.0)
Debug "me\Name: " + me\Name + ", me\iq: " + Int(me\iq)
Debug "you\Name: " + you\Name + ", you\iq: " + Int(you\iq)
Debug "Memory address of me: " + Hex(@me, #PB_Quad)
Debug "Memory address of you: " + Hex(@you, #PB_Quad)
Debug "Memory address held by *ptrTest: " + Hex(*ptrTest, #PB_Quad)
Debug "Value held by the variable memAddr: " + Hex(memAddr, #PB_Quad)
Debug "Memory address held by *ptrMemAddr: " + Hex(*ptrTest, #PB_Quad)
The following simple example works fine, so I can see no obvious reason why the "*" name prefix is needed.
Code: Select all
EnableExplicit
Procedure foo(myvar.i)
Debug("myvar=0x"+Hex(myvar,#PB_Quad))
Debug("peeki(myvar)="+Str(PeekI(myvar)))
EndProcedure
Define myvar.i
myvar=AllocateMemory(65536)
PokeI(@myvar,12345)
foo(@myvar)
The above example shows you can use an integer variable to hold a memory address but and is badly written and causes a memory leak (while running). It assigns the address of an allocated structured memory area to myvar and then throw it away bt assigning an arbitrary address to myvar without first freeing the memory which then results in a memory leak.
But, as you have echoed what the PB help says, i.e. that "Pointers' names include the '*' prefix at all times except within structures", why exactly does one need to specify the "*" prefix in front of a variable name?
Apart from being two completely different integer variables, does PB treat myvar and *myvar differently in some way, or is this just to improve readability of the code?
See Fred's comments in previous post.
The '*' part of the pointer name:
- Increases readability of the code immensely.
- Indicates the held value should reflect a memory address (it is a pointer).
- Reminds the need to possibly free allocated memory referenced by the pointer.
- Allows possible dereferencing (with structured pointers and using field notation).
- It ensures the variable is the right size to hold a memory address.