Page 1 of 1
					
				Structure pointer
				Posted: Tue Jul 30, 2013 11:53 am
				by Nubcake
				Hi 
Another newbish question but why is the pointer null in this case -> Is it because it doesn't point to anything? How do I correct this.
Code: Select all
EnableExplicit
Structure Pixel
 x.l
 y.l
Endstructure
Procedure.l someProc(someParam)
Define *Point.Pixel
*Point\x = 1 ;
Endprocedure
Edit: If i were to return a pointer from that procedure would I use PeekX to access the values of x or y or can I do something like *p.Pixel = @Pixel *p\x = 3... ?
 
			 
			
					
				Re: Structure pointer
				Posted: Tue Jul 30, 2013 12:01 pm
				by STARGÅTE
				Code: Select all
EnableExplicit
Structure Pixel
  x.l
  y.l
Endstructure
Procedure someProc(*Point.Pixel)
  *Point\x = 1 ;
Endprocedure
Define MyPixel.Pixel
someProc(@MyPixel)
Debug MyPixel\x
 
			 
			
					
				Re: Structure pointer
				Posted: Tue Jul 30, 2013 12:03 pm
				by Bisonte
				First : Don't use .l as return if you want to return memory adresses ! If you started this on x64 machines, it may causes IMA's, if the adress range is out of the 2GB range...
A pointer is only ONE adress ! If you want to store a structure here a simple example
Code: Select all
Structure Pixel
 x.l
 y.l
EndStructure
Procedure someProc(someParam)
  
Protected *Point.Pixel = AllocateMemory(SizeOf(Pixel))
If *Point
  Debug "pointer ready"
  *Point\x = 1
  *Point\y = someParam
  ProcedureReturn *Point
Else
  Debug "oh oh ... cannot allocatememory"
  ProcedureReturn #False  
EndIf
EndProcedure
Define *Point.Pixel
*Point = someProc(15)
If *Point
  Debug *Point\x
  Debug *Point\y
  FreeMemory(*Point)
EndIf
 
			 
			
					
				Re: Structure pointer
				Posted: Tue Jul 30, 2013 12:10 pm
				by Nubcake
				Bisonte wrote:
A pointer is only ONE adress ! If you want to store a structure here a simple example
Code: Select all
Structure Pixel
 x.l
 y.l
EndStructure
Procedure someProc(someParam)
  
Protected *Point.Pixel = AllocateMemory(SizeOf(Pixel))
If *Point
  Debug "pointer ready"
  *Point\x = 1
  *Point\y = someParam
  ProcedureReturn *Point
Else
  Debug "oh oh ... cannot allocatememory"
  ProcedureReturn #False  
EndIf
EndProcedure
Define *Point.Pixel
*Point = someProc(15)
If *Point
  Debug *Point\x
  Debug *Point\y
  FreeMemory(*Point)
EndIf
 
Yes this is what I was looking for thanks.
Edit: 
Code: Select all
 *Point.Pixel = AllocateMemory(SizeOf(Pixel)) 
 This pointer is not being freed ?
First : Don't use .l as return if you want to return memory adresses ! If you started this on x64 machines, it may causes IMA's, if the adress range is out of the 2GB range...
So I should use .i ?
Edit2: What's wrong with this code?
Code: Select all
Structure Pixel
  x.l
  y.l
EndStructure
Procedure.i proc(param)
  p.Pixel
  *ptr.Pixel = @p
  
  *ptr\x = param;
  *ptr\y = param;
  
  
  
  ProcedureReturn *ptr
  
EndProcedure
*p.Pixel = proc(32)
Debug *p\x
Debug *p\y
 
			 
			
					
				Re: Structure pointer
				Posted: Tue Jul 30, 2013 1:39 pm
				by Bisonte
				Free up the memory is always necessary. 
But in this little example not really, because if the program ends, PB will free up all pb interna like Sound, Images and so on...
in your second code is no allocation of memory.
Code: Select all
Structure Pixel
  x.l
  y.l
EndStructure
Procedure.i proc(param)
  *ptr.Pixel = AllocateMemory(SizeOf(Pixel))
 
  *ptr\x = param;
  *ptr\y = param;
  
  ProcedureReturn *ptr
 
EndProcedure
*p.Pixel = proc(32)
If *p 
  Debug *p\x
  Debug *p\y
EndIf
; and free
FreeMemory(*p)
If you use something like Variable.Pixel , PB allocate memory for this variable. so you can get the adress of this variable by @Variable.
But you make a new pointer in your example, so you have allocate the memory for this new pointer
 
			 
			
					
				Re: Structure pointer
				Posted: Tue Jul 30, 2013 3:00 pm
				by TI-994A
				Nubcake wrote:...So I should use .i ?
What's wrong with this code?
Code: Select all
Structure Pixel
  x.i
  y.i
EndStructure
Procedure proc(*p.Pixel, param)
  *p\x = param
  *p\y = param * 2
EndProcedure
Define p.Pixel
proc(@p, 32)
Debug p\x
Debug p\y
 
Hello Nubcake. The default type for PureBasic is the 
integer. So, if a variable is not explicitly declared, or defined without a type, PureBasic would automatically define it as an integer.
With reference to your code, if your requirement is simply to automate the assignment of values and the such, you may not wish to bother with all the memory management stuff. Instead, you could simply pass the address of the active structure to the procedure, and perform the required calculations and assignments on it directly; no pointers, no memory to allocate or free, and nothing to return either:
Code: Select all
Structure Pixel
  x.i
  y.i
EndStructure
Procedure proc(*p.Pixel, param)
  *p\x = param
  *p\y = param * 2
EndProcedure
Define p.Pixel
proc(@p, 32)
Debug p\x   ;returns 32
Debug p\y   ;returns 64
In fact, this is the approach that STARGÅTE had illustrated above. 

 
			 
			
					
				Re: Structure pointer
				Posted: Tue Jul 30, 2013 3:09 pm
				by Demivec
				Nubcake wrote:Edit2: What's wrong with this code?
Here's the code with comments to show where it went wrong:
Code: Select all
Structure Pixel
  x.l
  y.l
EndStructure
Procedure.i proc(param)
  p.Pixel
  *ptr.Pixel = @p  ;the pointer points to a memory location for the procedure's local variable 'p'
  
  *ptr\x = param;
  *ptr\y = param;
  
  
  
  ProcedureReturn *ptr ;you return the value of the pointer which is pointing to memory that is going to be freed and therefore doesn't point to anything
  ;You can correct this in two ways, the second method is the best way:
  ;1. You can make the variable P.Pixel a Static variable so that it won't be freed at the end of the procedure.  This will always show the last or current value
  ;    of the static variable so if you call the procedure multiple times it will use the same memory location but the procedure will keep overwriting the value
  ;    if it changes.
  ;2. You would allocate memory for the the variable which would then have to be freed outside of the procedure when you are done with it.
  ;     *ptr = AllocateMemory(SizeOf(Pixel)) ;always test if *ptr <> 0 to make sure this succeeds.
  
EndProcedure
*p.Pixel = proc(32)
Debug *p\x
Debug *p\y