What is the correct way to store a single structured type in a global variable

Just starting out? Need help? Post your questions and find answers here.
Quin
Addict
Addict
Posts: 1135
Joined: Thu Mar 31, 2022 7:03 pm
Location: Colorado, United States
Contact:

What is the correct way to store a single structured type in a global variable

Post by Quin »

Both of these examples produce the same output. My question is, what is the difference, and is there any time I should prefer using the pointer?

Code: Select all

EnableExplicit

Structure Config
BasePath$
List Files.s()
EndStructure

Global *Conf.Config = #Null
*Conf = AllocateStructure(Config)
With *Conf
\BasePath$ = "C:\"
AddElement(\Files())
\Files() = "Test"
AddElement(\Files())
\Files() = "Test2"
Debug \BasePath$ + " contains:"
ForEach \Files()
Debug \Files()
Next
EndWith
FreeStructure(*Conf)

Global Conf.Config
With Conf
\BasePath$ = "C:\"
AddElement(\Files())
\Files() = "Test"
AddElement(\Files())
\Files() = "Test2"
Debug \BasePath$ + " contains:"
ForEach \Files()
Debug \Files()
Next
EndWith
The docs are sort of unclear on this, they only talk about storing it in a map, list or similar, not in a single variable.
User avatar
Sicro
Enthusiast
Enthusiast
Posts: 563
Joined: Wed Jun 25, 2014 5:25 pm
Location: Germany
Contact:

Re: What is the correct way to store a single structured type in a global variable

Post by Sicro »

With the pointer variable variant, you can completely free the memory required for storing the structure data using FreeStructure().

With the variable variant, you cannot free the memory of basePath$, and it remains in RAM until the program is terminated. You can only free the list with FreeList().

Use the variant without pointers.

Pointer structures are useful if:
  • you want to access the same data in memory multiple times, but the data should only be in memory once.
  • you only get a pointer to data in memory from a function (e.g. a WinAPI function).
  • you don't want the data to be in memory yet, but you want to define the structure already, so that you can access the data easily later.
Image
Why OpenSource should have a license :: PB-CodeArchiv-Rebirth :: Pleasant-Dark (syntax color scheme) :: RegEx-Engine (compiles RegExes to NFA/DFA)
Manjaro Xfce x64 (Main system) :: Windows 10 Home (VirtualBox) :: Newest PureBasic version
Little John
Addict
Addict
Posts: 4803
Joined: Thu Jun 07, 2007 3:25 pm
Location: Berlin, Germany

Re: What is the correct way to store a single structured type in a global variable

Post by Little John »

Additionally to what Sicro wrote ...
Quin wrote: Sat Dec 07, 2024 7:14 pm The docs are sort of unclear on this, they only talk about storing it in a map, list or similar, not in a single variable.
I think you are referring to this text in the help for AllocateStructure():
This command is for advanced users and shouldn't be needed for most programs. It's often a better choice to use a structured array, list or map to store dynamic structured items.
Don't overestimate the meaning of the second sentence. The first sentence is the main message. :-)
Olli
Addict
Addict
Posts: 1264
Joined: Wed May 27, 2020 12:26 pm

Re: What is the correct way to store a single structured type in a global variable

Post by Olli »

I prefer InitializeStructure(), etc...

Code: Select all

Define *this.thing = AllocateMemory(SizeOf(thing) )
InitializeStructure(*this, thing)

; usual process

ClearStructure(*this, thing)
FreeMemory(*this)
In idle modes, it just stays the 8-bytes sized pointor *this in memory.
User avatar
mk-soft
Always Here
Always Here
Posts: 6320
Joined: Fri May 12, 2006 6:51 pm
Location: Germany

Re: What is the correct way to store a single structured type in a global variable

Post by mk-soft »

@Olli
Unnecessary ...
AllocateStructure and FreeStructure take care of this. And the additional 8 bytes of structure information don't hurt either.

@Quin
For global data, simply use a structure variable.
You have to deal with pointers a bit more. AllocateStructure is interesting for dynamic objects (i.e. multiple use). Here, for example, you can request memory for your own controls with the CanvasGadget and use the pointer with Set- Get- GadgetData.
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
Olli
Addict
Addict
Posts: 1264
Joined: Wed May 27, 2020 12:26 pm

Re: What is the correct way to store a single structured type in a global variable

Post by Olli »

mk-soft wrote:@Olli
Unnecessary ...
AllocateStructure and FreeStructure take care of this.
No, it does not take care of this. It does a specific job, but does not make all the jobs. Recursive object :

Code: Select all

Structure key
name.s
type.i
Array *ex(3) ; can point to an other key
EndStructure
And the additional 8 bytes of structure information don't hurt either.
Your argument is for the old method I use : just 8 bytes (and 4 bytes on X86). It is everything which stays after a total free of the memory when I work manually. So I agree : it doesn't hurt either.

For the whole structured object I allocate and free in memory, once the object is freeed, it just stays a pointer. It is not the way of AllocateStructure() and FreeStructure() where the whole structured variable ever stays in memory (excepted non-constant sized objects).

An other point : how to get an unique procedure to manage a recursive node, whatever the position of the node in the tree (root or not). If I differenciate by dupplicating all the set of the procedures handling a node, I am not sure the convenients not to type a '*' star character, are perfect...
User avatar
mk-soft
Always Here
Always Here
Posts: 6320
Joined: Fri May 12, 2006 6:51 pm
Location: Germany

Re: What is the correct way to store a single structured type in a global variable

Post by mk-soft »

To avoid an endless recursive memory request, it is correct to use pointer (also reported by the compiler). You can also specify the structure. With FreeStructure, only the parent is released, which is also correct
The same applies to pointers of objects such as LoadFont, LoadImage, etc. Here you have to release the objects before calling FreeStructure.

But I think you know this, since you pointed it out ;)

Code: Select all

Structure key
  name.s
  type.i
  Array *ex.key(3) ; can point to an other key
EndStructure

*pdata.key = AllocateStructure(key)
*pdata2.key = AllocateStructure(key)

Debug ArraySize(*pdata\ex())
*pdata\ex(0) = *pdata2
Debug ArraySize(*pdata\ex(0)\ex())
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
Post Reply