Page 1 of 1

dynamically allocate structure

Posted: Sat Jan 28, 2017 12:21 pm
by Keya
hello I'd like to dynamically allocate a structure (i dont want to allocate all 65536 elements if only 5 are needed sorta thing!)
I know this can be done with Arrays but im also trying to learn how to do it with AllocateMemory, but i must be missing something! as usual!

Code: Select all

#MAXITEMS=65536

Structure object
  width.l
  height.l
EndStructure

Structure objects
  *objects.object[#MAXITEMS]
EndStructure

Procedure InitStruct(quantity, *objects.objects)
  If quantity > #MAXITEMS: quantity = #MAXITEMS: EndIf
  *objects\objects = AllocateMemory(quantity * SizeOf(object))
EndProcedure


Define object.objects
objcnt = 5  ;how many to allocate
InitStruct(objcnt , @object)
Debug "object\objects=" + object\objects
For i = 0 To objcnt-1
  Debug object\objects[i]\width    ;crashing with null ptr reference, yet the object\objects ptr seems valid?
Next i

Re: dynamically allocate structure

Posted: Sat Jan 28, 2017 2:00 pm
by Fig
If i understand, you want kind of a redim like function, right ?

It will not work because your structure objects already weight 524288 octets...
If you reduce this structure to 1 element [1] you won't be able to access the extra element with index up to 1 because pb will error even if you enlarge the memory vailable. (because Pb is not aware of you action on the memory associate to the [])

Code: Select all

#MAXITEMS=65536
Structure o1
  width.l
  height.l
EndStructure
Procedure InitStruct(quantity)
  If quantity > #MAXITEMS: quantity = #MAXITEMS: EndIf
  Global *o3.o1= AllocateMemory(quantity * SizeOf(o1))
EndProcedure
objcnt=5
InitStruct(objcnt)
For i = 0 To objcnt-1
  *o4.o1=*o3+i*SizeOf(o1)
  Debug *o4\width
  Debug *o4\height
Next i
Is is close ?

Re: dynamically allocate structure

Posted: Sat Jan 28, 2017 2:08 pm
by Keya
Fig wrote:It will not work because your structure objects already weight 524288 octets...
It should only be that if it's fully allocated, but that's why i want to dynamically allocate it

Re: dynamically allocate structure

Posted: Sat Jan 28, 2017 2:31 pm
by Fig
Well i think, if you dynamically allocate, you can't acces with an index , because pb will prevent you.
Let's see what others think...

Re: dynamically allocate structure

Posted: Sat Jan 28, 2017 5:57 pm
by said
Hi,

Code: Select all

#MAXITEMS=65536

Structure object
  width.l
  height.l
  name.s
EndStructure

Structure objects
  *objects.object[#MAXITEMS]
EndStructure

Procedure InitStruct(quantity, *objects.objects)
    Protected i
    If quantity > #MAXITEMS: quantity = #MAXITEMS: EndIf
    For i=0 To quantity
        *objects\objects[i] = AllocateMemory(SizeOf(object))
    Next
    
EndProcedure


Define object.objects
objcnt = 5  ;how many to allocate
InitStruct(objcnt , @object)
Debug "object\objects=" + object\objects
For i = 0 To objcnt-1
  Debug object\objects[i]\width    ;crashing with null ptr reference, yet the object\objects ptr seems valid?
Next i

Re: dynamically allocate structure

Posted: Sat Jan 28, 2017 6:04 pm
by Keya
said, YES! thankyou! :) do you know if its possible to call AllocateMemory just once though? as im assuming the memory is contiguous, and the structure size is fixed

Re: dynamically allocate structure

Posted: Sat Jan 28, 2017 6:11 pm
by said
Keya wrote:said, YES! thankyou! :) do you know if its possible to call AllocateMemory just once though? as im assuming the memory is contiguous, and the structure size is fixed
you are welcome :D true the struct size is fixed and the array *objects in your structure objects is an array of addresses and it has contiguous memory but each address is free to point to anywhere! so i believe the answer is no

out of curiosity, was your issue fixed in that other thread ? http://www.purebasic.fr/english/viewtop ... 13&t=67509

Said

Re: dynamically allocate structure

Posted: Sat Jan 28, 2017 6:47 pm
by Fig
I thought you want to change the size of memory of your structure to allocate only 5 elements...
Is it the case in said's exemple ? :?

Code: Select all

Debug SizeOf(objects)
262144

Re: dynamically allocate structure

Posted: Sun Jan 29, 2017 12:40 am
by CSHW89
I hope, i understand your problem correctly. The variable 'objects' in 'objects' can not be a pointer, since you want that the memory is contiguous. But you need a pointer to store the allocated memory. You can easily return this. Additionally you dont need the MAXITEMS-constant.

Code: Select all

Structure object
  width.l
  height.l
EndStructure

Structure objects
  objects.object[0]
EndStructure

Procedure InitStruct(quantity)
  ProcedureReturn AllocateMemory(quantity * SizeOf(object))
EndProcedure


Define *objects.objects
objcnt = 5  ;how many to allocate
*objects = InitStruct(objcnt)
Debug "*objects=" + *objects
For i = 0 To objcnt-1
  Debug *objects\objects[i]\width
Next i

Re: dynamically allocate structure

Posted: Sun Jan 29, 2017 7:49 am
by Keya
fig yes i looked at Task Manager and went huh!? lol, was confused by the first loop

CSHW89, YES you've nailed it! Nice and simply too, i probably shouldn't be surprised, my brain was overcomplicating the problem with ptrs to ptrs i think :(

Really nice simple example of keeping memory in check when array size can get large but is often small :) woohoo!

Re: dynamically allocate structure

Posted: Sun Jan 29, 2017 8:19 am
by Keya
I modified CSHW89's example to go TWO LEVELS! ie. dynalloc parent nodes with dynalloc child nodes :) So not only is memory only being allocated for the required number of parents, but now each parent also only gets enough memory allocated for their independent required number of children. Groovy! :) I'm guessing there's not really a limit how deep it can go but i don't think i'd ever need more than two anyway! I guess I also could've combined the parent/child structures so that instead of Parent-> Child it just points to Parent->Parent (and can then go on depth unlimited), with the lower one obviously having a child relationship to the higher one, but this works!

Code: Select all

Structure child
  width.l
  height.l
EndStructure

Structure childobj
  children.child[0]
EndStructure


Structure parent
  width.l
  height.l
  numchilds.l
  *pchildren.childobj  
EndStructure

Structure parentobj
  pparent.parent[0]
EndStructure



Define *parent.parentobj
parentcnt = 5  ;how many to allocate
*parent = AllocateMemory(parentcnt * SizeOf(parent))

For i = 0 To parentcnt-1
  ;// PARENT NODES
  Debug "pw=" + *parent\pparent[i]\width
  
  ;// CHILD NODES
   *parent\pparent[i]\numchilds = Random(4,1)
   *parent\pparent[i]\pchildren = AllocateMemory(*parent\pparent[i]\numchilds * SizeOf(child))
   For curchild = 0 To *parent\pparent[i]\numchilds-1
     Debug " cw"+Str(curchild)+"=" + *parent\pparent[i]\pchildren\children[curchild]\width
   Next curchild  
Next i

Re: dynamically allocate structure

Posted: Sun Jan 29, 2017 9:24 am
by Keya
Keya wrote:I guess I also could've combined the parent/child structures so that instead of Parent-> Child it just points to Parent->Parent (and can then go on depth unlimited), with the lower one obviously having a child relationship to the higher one
GREAT IDEA LETS TRY THAT lol

Code: Select all

Structure person
  width.l
  height.l
  numchilds.l
  *pchildren.personobj  ;"self-chaining"? singly linked list
EndStructure

Structure personobj
  pperson.person[0]
EndStructure


Define *person.personobj
personcnt = 5  ;how many to allocate
*person = AllocateMemory(personcnt * SizeOf(person))

For i = 0 To personcnt-1
  ;// person
  Debug "pw=" + *person\pperson[i]\width
  
  ;// Add children
   *person\pperson[i]\numchilds = Random(4,1)
   *person\pperson[i]\pchildren = AllocateMemory(*person\pperson[i]\numchilds * SizeOf(person))
   For curchild = 0 To *person\pperson[i]\numchilds-1
     Debug " cw"+Str(curchild)+"=" + Str( *person\pperson[i]\pchildren\pperson[curchild]\width )
     ;// Could add children to children here
   Next curchild
   
Next i
ie.*person (great grandfather) can point to *person (grandfather) can point to *person (father) can point to *person (child) etc, and each person can have unlimited (resource-limited) amount of children, as can their children, without consuming any more memory than is absolutely required

Re: dynamically allocate structure

Posted: Mon Jan 30, 2017 5:56 pm
by Kwai chang caine
Very interesting
Thanks for sharing 8)