dynamically allocate structure

Just starting out? Need help? Post your questions and find answers here.
User avatar
Keya
Addict
Addict
Posts: 1890
Joined: Thu Jun 04, 2015 7:10 am

dynamically allocate structure

Post 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
User avatar
Fig
Enthusiast
Enthusiast
Posts: 352
Joined: Thu Apr 30, 2009 5:23 pm
Location: Côtes d'Azur, France

Re: dynamically allocate structure

Post 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 ?
Last edited by Fig on Sat Jan 28, 2017 2:23 pm, edited 4 times in total.
There are 2 methods to program bugless.
But only the third works fine.

Win10, Pb x64 5.71 LTS
User avatar
Keya
Addict
Addict
Posts: 1890
Joined: Thu Jun 04, 2015 7:10 am

Re: dynamically allocate structure

Post 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
User avatar
Fig
Enthusiast
Enthusiast
Posts: 352
Joined: Thu Apr 30, 2009 5:23 pm
Location: Côtes d'Azur, France

Re: dynamically allocate structure

Post 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...
There are 2 methods to program bugless.
But only the third works fine.

Win10, Pb x64 5.71 LTS
said
Enthusiast
Enthusiast
Posts: 342
Joined: Thu Apr 14, 2011 6:07 pm

Re: dynamically allocate structure

Post 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
User avatar
Keya
Addict
Addict
Posts: 1890
Joined: Thu Jun 04, 2015 7:10 am

Re: dynamically allocate structure

Post 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
said
Enthusiast
Enthusiast
Posts: 342
Joined: Thu Apr 14, 2011 6:07 pm

Re: dynamically allocate structure

Post 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
User avatar
Fig
Enthusiast
Enthusiast
Posts: 352
Joined: Thu Apr 30, 2009 5:23 pm
Location: Côtes d'Azur, France

Re: dynamically allocate structure

Post 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
There are 2 methods to program bugless.
But only the third works fine.

Win10, Pb x64 5.71 LTS
CSHW89
User
User
Posts: 30
Joined: Thu Sep 09, 2010 2:47 pm

Re: dynamically allocate structure

Post 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
Image Image Image
User avatar
Keya
Addict
Addict
Posts: 1890
Joined: Thu Jun 04, 2015 7:10 am

Re: dynamically allocate structure

Post 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!
User avatar
Keya
Addict
Addict
Posts: 1890
Joined: Thu Jun 04, 2015 7:10 am

Re: dynamically allocate structure

Post 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
User avatar
Keya
Addict
Addict
Posts: 1890
Joined: Thu Jun 04, 2015 7:10 am

Re: dynamically allocate structure

Post 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
User avatar
Kwai chang caine
Always Here
Always Here
Posts: 5494
Joined: Sun Nov 05, 2006 11:42 pm
Location: Lyon - France

Re: dynamically allocate structure

Post by Kwai chang caine »

Very interesting
Thanks for sharing 8)
ImageThe happiness is a road...
Not a destination
Post Reply