Memory reallocation within a sub function...

Just starting out? Need help? Post your questions and find answers here.
User avatar
SnowyDog
User
User
Posts: 33
Joined: Tue Jun 10, 2014 8:18 pm

Re: Memory reallocation within a sub function...

Post by SnowyDog »

Demivec, this is incredibly helpful. Thank you for taking the time to post this.

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

Code: Select all

@*MemPtr
makes no sense as you would be dereferencing the pointer twice.

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.

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)
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?
Fred
Administrator
Administrator
Posts: 18161
Joined: Fri May 17, 2002 4:39 pm
Location: France
Contact:

Re: Memory reallocation within a sub function...

Post by Fred »

If you don't attach a structure to your pointer, using the pointer notation or just a ".i" variable is exactly the same (the pointer notation obviously make it clear it's a pointer). If you attach a structure, a pointer behaves differently than a variable as you can change the pointed memory area and use the structure to access it, while a standard structured variable can't be moved accross memory.
User avatar
Demivec
Addict
Addict
Posts: 4260
Joined: Mon Jul 25, 2005 3:51 pm
Location: Utah, USA

Re: Memory reallocation within a sub function...

Post by Demivec »

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

Code: Select all

@*MemPtr
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.
User avatar
SnowyDog
User
User
Posts: 33
Joined: Tue Jun 10, 2014 8:18 pm

Re: Memory reallocation within a sub function...

Post by SnowyDog »

Thanks again for your time, Demivec. I'm sure this info will be helpful to others too.
Post Reply