Page 1 of 1

How to copy a structure

Posted: Wed Dec 19, 2007 6:35 am
by Mistrel
This is pretty simple but still pertinent to Tricks 'n' Tips.

Code: Select all

Define box1.RECT

box1\left=1
box1\top=2
box1\right=3
box1\bottom=4

mem=AllocateMemory(SizeOf(RECT))

CopyMemory(@box1.RECT,mem,SizeOf(RECT))

*box2.RECT=mem

Debug *box2\left
Debug *box2\top
Debug *box2\right
Debug *box2\bottom

Posted: Wed Dec 19, 2007 10:52 am
by Fred
Just ensure there is no string in your structure, or you will run into problems.

Posted: Wed Dec 19, 2007 10:53 am
by dige
please note that works not with included strings...

Posted: Wed Dec 19, 2007 10:54 am
by dige
ha! Fred was faster :D

Posted: Wed Dec 19, 2007 5:24 pm
by Mistrel
You can with fixed strings. Thanks, Fred.

Code: Select all

Structure ARECT
	left.l
	top.l
	right.l
	bottom.l
	string.s{6}
EndStructure

Define box1.ARECT

box1\left=1
box1\top=2
box1\right=3
box1\bottom=4
box1\string="Hello!"

mem=AllocateMemory(SizeOf(ARECT))

CopyMemory(@box1.ARECT,mem,SizeOf(ARECT))

*box2.ARECT=mem

Debug *box2\left
Debug *box2\top
Debug *box2\right
Debug *box2\bottom
Debug *box2\string

Posted: Wed Dec 19, 2007 8:04 pm
by Joakim Christiansen
Fred wrote:Just ensure there is no string in your structure, or you will run into problems.
That's why we need you to make a function that works with strings too ;)

Posted: Wed Dec 19, 2007 8:07 pm
by srod
Joakim Christiansen wrote:
Fred wrote:Just ensure there is no string in your structure, or you will run into problems.
That's why we need you to make a function that works with strings too ;)
Copying a structure containing strings to one created dynamically with AllocateMemory() requires that you take steps to free the copies when the memory is released as Purebasic will not do this for you. Still, it's easy enough. :)

Posted: Wed Dec 19, 2007 9:42 pm
by Mistrel
If we had TypeOf() we could make a macro for this.

But from what I understand this isn't possible with PureBasic's type system.

Posted: Wed Dec 19, 2007 10:17 pm
by Psychophanta
Fred wrote:Just ensure there is no string in your structure, or you will run into problems.
Should not be:
Just ensure there is no string in your structure, or you could run into problems.
:?:
Because this works as expected without errors :? :?:

Code: Select all

Structure ARECT 
   left.l 
   top.l 
   right.l 
   bottom.l 
   string.s{6}
   another$
   another.s
   anotherone$
EndStructure 

Define box1.ARECT 

box1\left=1 
box1\top=2 
box1\right=3 
box1\bottom=4 
box1\string="Hello!"
box1\another$="Hellooo!"
box1\another="Helloooooooo!.s"
box1\anotherone$="Hiiiiiiiiooooooo!"

*box2.ARECT=AllocateMemory(SizeOf(ARECT)) 

CopyMemory(@box1.ARECT,*box2.ARECT,SizeOf(ARECT)) 

Debug *box2\left 
Debug *box2\top 
Debug *box2\right 
Debug *box2\bottom 
Debug *box2\string
Debug *box2\another$
Debug *box2\another
Debug *box2\anotherone$

Posted: Wed Dec 19, 2007 10:24 pm
by srod
That is what I would call a 'shallow copy' of the strings as only the underlying pointers are copied and can lead to all kinds of problems.

E.g. altering one of the string fields in box1 could seriously invalidate the fields of box2. The following (on my system at least) shows the problem in that the 'another$' field of box2 is corrupted after altering the corresponding field in box1.

Code: Select all

Structure ARECT 
   left.l 
   top.l 
   right.l 
   bottom.l 
   string.s{6} 
   another$ 
   another.s 
   anotherone$ 
EndStructure 

Define box1.ARECT 

box1\left=1 
box1\top=2 
box1\right=3 
box1\bottom=4 
box1\string="Hello!" 
box1\another$="Hellooo!" 
box1\another="Helloooooooo!.s" 
box1\anotherone$="Hiiiiiiiiooooooo!" 

*box2.ARECT=AllocateMemory(SizeOf(ARECT)) 

CopyMemory(@box1.ARECT,*box2.ARECT,SizeOf(ARECT)) 

box1\another$="OYdddddddddddddddddddddddddddddddddddddddddddddddddd!"

Debug *box2\another$ 
The problem here is that the original string pointer copied to box2 has been invalidated by the line :

Code: Select all

box1\another$="OYdddddddddddddddddddddddddddddddddddddddddddddddddd!"
In this respect, I would heed Fred's original words carefully! :wink:

Posted: Wed Dec 19, 2007 10:28 pm
by Psychophanta
Aha!, you refreshed my mem :)
Then there is no problem if the strings are not touched? :?

Posted: Wed Dec 19, 2007 10:30 pm
by srod
Yes, but imagine, for example, that the original structure is local to a procedure, then on exit from the procedure all string fields copied to dynamic memory will be instantly invalidated!

A risky business and not one to be found in 'srod's good guide to programming!' :)

Posted: Wed Dec 19, 2007 10:31 pm
by Psychophanta
Yes, then Fred was right when said "will" :wink:

Posted: Thu Dec 20, 2007 1:53 pm
by Ollivier
In order to copy a structure, there's a solution but you must notify the structure to the procedure via a specific string.

http://www.purebasic.fr/english/viewtop ... highlight=