www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - array copy/ref question

reply Brian Sturk <bsturk comcast.net> writes:
I'm trying to get a handle on the array assignment, slicing operations and am a
little confused.  The last copy gives me an "overlapping array copy".  Both
arrays have a length of 4.  Is it that I cannot copy from one dynamic array to
another (even if the same size)?

If I'm reading the docs correctly the copy syntax is to have the lhs use the
brackets.

Here is my program:

import std.stdio;

///////////////////////////////////

void
main( string[] args )
{
    int[] test = [ 1, 2, 3, 4 ];
    int[] copy;

    copy = test;

    test[1] = 7;

    writefln( "Ref: test[1] %d copy[1] %d", test[1], copy[1] );

    assert( test[1] == 7 );
    assert( copy[1] == 7 );

    copy    = test[];
    test[1] = 9;

    assert( test[1] == 9 );
    assert( copy[1] == 9 );

    writefln( "Alt ref syntax: test[1] %d copy[1] %d", test[1], copy[1] );

    writefln( "%d %d", test.length, copy.length );

    copy[]  = test;     /* Want to copy, get Error: overlapping array copy */
    test[1] = 11;

    assert( test[1] == 11 );
    assert( copy[1] == 9 );

    writefln( "Copy: test[1] %d copy[1] %d", test[1], copy[1] );
}

Output:

 ./test_ref
Ref: test[1] 7 copy[1] 7
Alt ref syntax: test[1] 9 copy[1] 9
4 4
Error: overlapping array copy
Aug 11 2008
parent reply Lars Ivar Igesund <larsivar igesund.net> writes:
Brian Sturk wrote:

 I'm trying to get a handle on the array assignment, slicing operations and
 am a little confused.  The last copy gives me an "overlapping array copy".
  Both arrays have a length of 4.  Is it that I cannot copy from one
 dynamic array to another (even if the same size)?

It means you are trying to copy from the same memory you are copying to - your arrays reference the same memory. -- Lars Ivar Igesund blog at http://larsivi.net DSource, #d.tango & #D: larsivi Dancing the Tango
Aug 11 2008
next sibling parent reply Brian Sturk <bsturk comcast.net> writes:
Lars Ivar Igesund Wrote:

 Brian Sturk wrote:
 
 I'm trying to get a handle on the array assignment, slicing operations and
 am a little confused.  The last copy gives me an "overlapping array copy".
  Both arrays have a length of 4.  Is it that I cannot copy from one
 dynamic array to another (even if the same size)?

It means you are trying to copy from the same memory you are copying to - your arrays reference the same memory.

Hi there, Thanks for the clarification, sounds like I need to do a memcpy to do a true copy. ~telengard
Aug 11 2008
next sibling parent "Jarrett Billingsley" <kb3ctd2 yahoo.com> writes:
"Brian Sturk" <bsturk comcast.net> wrote in message 
news:g7qoh0$2vvr$1 digitalmars.com...
 Lars Ivar Igesund Wrote:

 Brian Sturk wrote:

 I'm trying to get a handle on the array assignment, slicing operations 
 and
 am a little confused.  The last copy gives me an "overlapping array 
 copy".
  Both arrays have a length of 4.  Is it that I cannot copy from one
 dynamic array to another (even if the same size)?

It means you are trying to copy from the same memory you are copying to - your arrays reference the same memory.

Hi there, Thanks for the clarification, sounds like I need to do a memcpy to do a true copy.

Nope, it's memmove you're looking for. memcpy over overlapping memory regions has undefined behavior. Incidentally, for the same reasons overlapping slice copies are illegal -- to allow for the use of faster hardware copies that disallow overlapping regions.
Aug 11 2008
prev sibling parent reply Sclytrack <sclytrack pi.be> writes:
== Extrait de l'article de « Jesse Phillips (jessekphillips gmail.com) »
 On Tue, 12 Aug 2008 02:42:17 +0000, Jesse Phillips wrote:
 main( string[] args )
 {
     int[] test = [ 1, 2, 3, 4 ];
     int[] copy = new int[4];

     copy[]  = test;
     test[1] = 11;

     assert( test[1] == 11 );
     assert( copy[1] == 2 );

     writefln( "Copy: test[1] %d copy[1] %d", test[1], copy[1] );
 }


copy = test.dup; //Is this what you want?
Aug 12 2008
parent telengard <bsturk comcast.net> writes:
Sclytrack Wrote:

 == Extrait de l'article de « Jesse Phillips (jessekphillips gmail.com) »
 On Tue, 12 Aug 2008 02:42:17 +0000, Jesse Phillips wrote:
 main( string[] args )
 {
     int[] test = [ 1, 2, 3, 4 ];
     int[] copy = new int[4];

     copy[]  = test;
     test[1] = 11;

     assert( test[1] == 11 );
     assert( copy[1] == 2 );

     writefln( "Copy: test[1] %d copy[1] %d", test[1], copy[1] );
 }


copy = test.dup; //Is this what you want?

Just found that and it does seem to do what I want. Seems like I have other issues though from reading the responses. Much to learn. :) I think I'm projecting too much of my python stuff onto D. I thought I could just slice an array into a newly declared one as I would in python. thanks for the info everyone, much appreciated. ~telengard
Aug 12 2008
prev sibling next sibling parent Jesse Phillips <jessekphillips gmail.com> writes:
On Mon, 11 Aug 2008 21:20:32 -0400, Brian Sturk wrote:

 Lars Ivar Igesund Wrote:
 
 Brian Sturk wrote:
 
 I'm trying to get a handle on the array assignment, slicing
 operations and am a little confused.  The last copy gives me an
 "overlapping array copy".
  Both arrays have a length of 4.  Is it that I cannot copy from one
 dynamic array to another (even if the same size)?

It means you are trying to copy from the same memory you are copying to - your arrays reference the same memory.

Hi there, Thanks for the clarification, sounds like I need to do a memcpy to do a true copy. ~telengard

The problem is at the top of the program, this should give you the same error: main( string[] args ) { int[] test = [ 1, 2, 3, 4 ]; int[] copy; copy = test; test[1] = 7; writefln( "Ref: test[1] %d copy[1] %d", test[1], copy[1] ); assert( test[1] == 7 ); assert( copy[1] == 7 ); copy = test[]; test[1] = 9; assert( test[1] == 9 ); assert( copy[1] == 9 ); writefln( "Alt ref syntax: test[1] %d copy[1] %d", test[1], copy[1] ); writefln( "%d %d", test.length, copy.length ); copy[] = test; /* Want to copy, get Error: overlapping array copy */ test[1] = 11; assert( test[1] == 11 ); assert( copy[1] == 9 ); writefln( "Copy: test[1] %d copy[1] %d", test[1], copy[1] ); } You created copy and told it to point to test, you would need to initialize copy to its own memory. main( string[] args ) { int[] test = [ 1, 2, 3, 4 ]; int[] copy = new int[4]; copy[] = test; test[1] = 11; assert( test[1] == 11 ); assert( copy[1] == 2 ); writefln( "Copy: test[1] %d copy[1] %d", test[1], copy[1] ); }
Aug 11 2008
prev sibling next sibling parent Jesse Phillips <jessekphillips gmail.com> writes:
On Tue, 12 Aug 2008 02:42:17 +0000, Jesse Phillips wrote:

 main( string[] args )
 {
     int[] test = [ 1, 2, 3, 4 ];
     int[] copy = new int[4];
 
     copy[]  = test;
     test[1] = 11;
 
     assert( test[1] == 11 );
     assert( copy[1] == 2 );
 
     writefln( "Copy: test[1] %d copy[1] %d", test[1], copy[1] );
 }

I know I created that first one to be smaller, here is what it was supposed to be. void main( string[] args ) { int[] test = [ 1, 2, 3, 4 ]; int[] copy; copy = test; copy[] = test; }
Aug 12 2008
prev sibling next sibling parent "Koroskin Denis" <2korden gmail.com> writes:
On Tue, 12 Aug 2008 18:12:52 +0400, Jesse Phillips  
<jessekphillips gmail.com> wrote:

 On Tue, 12 Aug 2008 02:42:17 +0000, Jesse Phillips wrote:

 main( string[] args )
 {
     int[] test = [ 1, 2, 3, 4 ];
     int[] copy = new int[4];

     copy[]  = test;
     test[1] = 11;

     assert( test[1] == 11 );
     assert( copy[1] == 2 );

     writefln( "Copy: test[1] %d copy[1] %d", test[1], copy[1] );
 }

I know I created that first one to be smaller, here is what it was supposed to be. void main( string[] args ) { int[] test = [ 1, 2, 3, 4 ]; int[] copy; copy = test; copy[] = test; }

It can be rewritten as following: void main() { int[] test = [ 1, 2, 3, 4 ]; test[] = test; } Do you see now that arrays overlap? It is illegal, use custom routines if you suspect that your data overlaps.
Aug 12 2008
prev sibling parent Jesse Phillips <jessekphillips gmail.com> writes:
On Tue, 12 Aug 2008 14:51:39 +0000, Sclytrack wrote:

 == Extrait de l'article de Ā«Ā Jesse Phillips (jessekphillips gmail.com)Ā Ā»
 On Tue, 12 Aug 2008 02:42:17 +0000, Jesse Phillips wrote:
 main( string[] args )
 {
     int[] test = [ 1, 2, 3, 4 ];
     int[] copy = new int[4];

     copy[]  = test;
     test[1] = 11;

     assert( test[1] == 11 );
     assert( copy[1] == 2 );

     writefln( "Copy: test[1] %d copy[1] %d", test[1], copy[1] );
 }


copy = test.dup; //Is this what you want?

Yes, I probably should have mentioned this as well. However I did wish to give him an idea of what was causing the overlapping. I should also note that with the demonstrated method you are able to copy into a slice of an array. copy[1..5] = test[4..8]; or even test[0..2] = test[3..5]; // As long as they don't overlap :)
Aug 13 2008