Page 1 of 1

Copy structure with pointer (v4.40 work around)

Posted: Fri Nov 20, 2009 6:33 pm
by Demivec
Code updated for 5.20+ (same as CopyStructure())

PureBasic v4.40b7 now supports a simple way to copy structures with

Code: Select all

this.test = that.test  ;works great
but this does not work when using pointers.

Code: Select all

*this.test = *that.test  ;doesn't work for copying structure's contents
Here's a simple idea to get around this and it only costs an additional structure definition.

The simple code below copies the 'test' structure via pointers by using the 'work' structure so that the structure will be dereferenced for copying:

Code: Select all

;original structure
Structure test
  index.i
  phrase.s
EndStructure

;work structure for copying
Structure work
  test.test[0]
EndStructure

Procedure copyByPtr(*a.work,*b.work)
  *b\test = *a\test
EndProcedure

Define V1.test, V2.test

V1\index = 5
V1\phrase = "hello"

Debug "----source----"
Debug V1\index
Debug V1\phrase

Debug "----destination contents before----"
Debug V2\index
Debug V2\phrase

copyByPtr(@V1,@V2)
Debug "----destination contents after----"
Debug V2\index
Debug V2\phrase
Hopefully this work around won't be necessary in v4.50. :wink:

Re: Copy structure with pointer (v4.40 work around)

Posted: Fri Nov 20, 2009 7:10 pm
by srod
Pretty neat. 8)

Re: Copy structure with pointer (v4.40 work around)

Posted: Fri Nov 20, 2009 7:25 pm
by Mistrel
Why would you expect *this.test = *that.test to work? :?

Re: Copy structure with pointer (v4.40 work around)

Posted: Fri Nov 20, 2009 7:31 pm
by srod
He is talking about copying the structure pointed to by one pointer to the structure pointed to by another pointer.

Although you have a good point there in that *ptr1 = *ptr2 is always going to be a shallow copy of pointers (as opposed to a 'deep copy' if the underlying structure memory).

@Demivec, you will always need a workaround of sorts because *this.test = *that.test MUST absolutely remain a shallow copy of pointers.

Re: Copy structure with pointer (v4.40 work around)

Posted: Fri Nov 20, 2009 8:28 pm
by Demivec
[quote = "Mistre"]Why would you expect *this.test = *that.test to work?[/quote]
@Mistrel: I wouldn't. I am familiar with how an assignment works between pointer variables. I don't want that to change. What I do want is that there be a way to copy the contents of a structure, whose address I have in a structured pointer, to another another address that is pointed to by another structured pointer.
srod wrote:He is talking about copying the structure pointed to by one pointer to the structure pointed to by another pointer.

Although you have a good point there in that *ptr1 = *ptr2 is always going to be a shallow copy of pointers (as opposed to a 'deep copy' if the underlying structure memory).

@Demivec, you will always need a workaround of sorts because *this.test = *that.test MUST absolutely remain a shallow copy of pointers.
@srod: regarding always vs. temporary workarounds, I am hoping that some of the suggestion that have been made regarding this are made effective. According to my notes there are basically two suggestions, one is to implement a compile-time function that looks like this:

Code: Select all

CopyStructure(*source,*destination,structure)
the other suggestion is to use the structure punction like this:

Code: Select all

*source\ = *destination\ ;
I favor the first one, though technically, either of these would be fine with me. :D

Re: Copy structure with pointer (v4.40 work around)

Posted: Fri Nov 20, 2009 11:29 pm
by Rescator
Copying the structure from one pointer to the structure of another pointer makes no sense and sounds dangerous even.

Wouldn't "this.test = *that.test" be much more logical? (does that work?, haven't tested yet!)

PS! I kinda like the CopyStructure() as well, and it's much more explicit. (the other way is too accident prone, a simple typo and you'd be copying strucures who knows where).

Re: Copy structure with pointer (v4.40 work around)

Posted: Sat Nov 21, 2009 9:55 am
by srod
"this.test = *that.test"
Presently that simply copies the pointers and really should not be changed else we'd be screwing up pointer arithmetic and the like. A deep structure copy performed through pointers should be done, inmo, through some other means, through one of the methods outlined by Demivec perhaps.

Re: Copy structure with pointer (v4.40 work around)

Posted: Sat Nov 21, 2009 12:23 pm
by einander
Is'nt simpler this :?:

Code: Select all

 Structure test
   Index.i
   phrase.s
EndStructure

Define V1.test, V2.test
   
V1\Index = 5
V1\phrase = "hello"
   
Debug "----source----"
Debug V1\Index
Debug V1\phrase
   
Debug "----destination contents before----"
Debug V2\Index
Debug V2\phrase
  
CopyMemory(@V1,@V2,SizeOf(test))
   
Debug "----destination contents after----"
Debug V2\Index
Debug V2\phrase

Re: Copy structure with pointer (v4.40 work around)

Posted: Sat Nov 21, 2009 12:39 pm
by srod
Doesn't copy strings; only their pointers. Free one structure and you will invalidate the string pointer in the other.

Re: Copy structure with pointer (v4.40 work around)

Posted: Sat Nov 21, 2009 12:53 pm
by Seymour Clufley
srod wrote:Presently that simply copies the pointers and really should not be changed else we'd be screwing up pointer arithmetic and the like. A deep structure copy performed through pointers should be done, inmo, through some other means...
Surely the best, simplest, most obvious way to do a deep structure copy would be with a command:

Code: Select all

CopyStructure(@a,@b)
Doing it with a=b is just confusing, IMHO.

Re: Copy structure with pointer (v4.40 work around)

Posted: Sat Nov 21, 2009 12:59 pm
by srod
I would say that that could be implemented quite easily since we now have structure copying added to PB through a = b etc.

Re: Copy structure with pointer (v4.40 work around)

Posted: Sat Nov 21, 2009 5:16 pm
by Demivec
einander wrote:Is'nt simpler this :?:
@einander: It is simpler but as srod pointed out, it doesn't accomplish a deep copy. Secondly, the original code example was rigged so that it would demonstrate doing a copy with pointers. Otherwise it could have been done even simpler with V2.test = V1.test. :wink:

I realize people may not even realize that structure copying is now native as of the v4.40 betas. That's one reason I posted this thread. It shows one way to utilize this feature with structure pointers and the structure data they point to.

Re: Copy structure with pointer (v4.40 work around)

Posted: Sat Nov 21, 2009 8:23 pm
by Polly
Maybe this is the best workaround for the time being? Only only one init command per structure (+1 generic macro):

Code: Select all

Macro InitCopyStruct(struc)

   Structure work#struc
     struc.struc[0]
   EndStructure
   
   Procedure copyStruct#struc(*a.work#struc,*b.work#struc)
     *b\struc = *a\struc
   EndProcedure

EndMacro

;original structure
Structure test
  index.i
  phrase.s
EndStructure

Structure test2
  index.i
  phrase.s
EndStructure

InitCopyStruct(test)
InitCopyStruct(test2)


Define V1.test, V2.test, V3.test2

V1\index = 5
V1\phrase = "hello"

Debug "----source----"
Debug V1\index
Debug V1\phrase

Debug "----destination contents before----"
Debug V2\index
Debug V2\phrase

copyStructTest(@V1,@V2)
Debug "----destination contents after----"
Debug V2\index
Debug V2\phrase

*pV2.test=@V2
*pV3.test2=@V3
copyStructTest2(*pV2,*pV3)
Debug "----destination contents after----"
Debug V3\index
Debug V3\phrase

Re: Copy structure with pointer (v4.40 work around)

Posted: Sat Nov 21, 2009 9:11 pm
by einander
@Demivec:
I realize people may not even realize that structure copying is now native as of the v4.40 betas.
I`ve missed this.
Thanks for the tip!
@Srod:
:oops: