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

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 ?
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
