array swap

This is a discussion on array swap within the C Programming forums, part of the General Programming Boards category; Hi i want to swap the contents of two 2-dimensioned arrays,without copying all the contents one by one. i try ...

  1. #1
    Registered User
    Join Date
    Dec 2003
    Posts
    1

    array swap

    Hi
    i want to swap the contents of two 2-dimensioned arrays,without copying all the contents one by one.
    i try something like this but it doesn't work :

    double v[512][8192];
    double v_prev[512][8192];

    double (*temp)[512][8192];

    temp=v;
    v_prev=temp;

    thanks

  2. #2
    Been here, done that.
    Join Date
    May 2003
    Posts
    1,156

    Re: array swap

    Originally posted by netmg
    Hi
    i want to swap the contents of two 2-dimensioned arrays,without copying all the contents one by one.
    i try something like this but it doesn't work :

    double v[512][8192];
    double v_prev[512][8192];

    double (*temp)[512][8192];

    temp=v;
    v_prev=temp;

    thanks
    Nope, can't do that.

    Set up an array
    int v_index[512];
    with each entry initialized to it's index
    Code:
    for (j=0; j<512; j++)
    {
        v_index[j] = j;
    }
    Then when you test v[x][y] with v[x+1][y] you would use:
    Code:
    if (v[vindex[x]][y] > v[vindex[x+1]][y])
    {
        i = vindex[x];
        vindex[x] = vindex[x+1];
        vindex[x+1] = i;
    }
    This way you sort the indecies instead and always reference the array thru the index array.
    Definition: Politics -- Latin, from
    poly meaning many and
    tics meaning blood sucking parasites
    -- Tom Smothers

  3. #3
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,796
    >Nope, can't do that.
    Anything can be done with sufficient creativity and a little daring:
    Code:
    #include <stdio.h>
    
    void show_vector ( int v[2][5] )
    {
      int i, j;
    
      for ( i = 0; i < 2; i++ ) {
        for ( j = 0; j < 5; j++ )
          printf ( "%d ", v[i][j] );
        printf ( "\n" );
      }
      printf ( "\n" );
    }
    
    int main ( void )
    {
      struct vector { int v[2][5]; };
      struct vector v = {
        {
          {1,2,3,4,5},
          {6,7,8,9,0}
        }
      };
      struct vector v_prev = {
        {
          {0,9,8,7,6},
          {5,4,3,2,1}
        }
      };
      struct vector temp;
    
      show_vector ( v.v );
      show_vector ( v_prev.v );
      temp = v;
      v = v_prev;
      v_prev = v;
      show_vector ( v.v );
      show_vector ( v_prev.v );
    
      return 0;
    }
    My best code is written with the delete key.

  4. #4
    Been here, done that.
    Join Date
    May 2003
    Posts
    1,156
    Originally posted by Prelude
    >Nope, can't do that.
    Anything can be done with sufficient creativity and a little daring:
    [/code]
    OK,OK, I stand chastised. Let me rephrase:

    Assuming you are new to programming, you will find it difficult and potentially obtuse to use the technique you are attempting to use. There are easier ways for the beginner, such as:
    add the rest of my post here

    But it can be done if you have enough experience, knowledge, and you don't like the next person that has to look at your code....
    Definition: Politics -- Latin, from
    poly meaning many and
    tics meaning blood sucking parasites
    -- Tom Smothers

  5. #5
    and the hat of wrongness Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    32,344
    Depends what you mean by swap

    If you're looking to just choose between two arrays, you should just go with
    double v[2][512][8192];
    int prev = 0; // or prev = 1 if you want the other one

    Your array is typically 32MB in size, which you really don't want to be copying if at all possible.
    But if you insist....
    double v[512][8192];
    double v_prev[512][8192];
    double temp[512][8192];
    memcpy( temp, v, sizeof(temp) );
    memcpy( v_prev, v, sizeof(v_prev) );
    memcpy( v, temp, sizeof(v) );
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.
    I support http://www.ukip.org/ as the first necessary step to a free Europe.

  6. #6
    Super Moderator VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,586
    And in this case I would not use memcpy because it only copies bytes at a time.


    This is assuming the arrays are linear, if not -> offset=(row*width+column)
    Code:
    //Assumes that Temp is a valid pointer to an array that is the 
    //same size as Array1 and Array2
    //Array1 and Array2 must be the same size
    //ArraySize must be specified in total bytes
    void CopyArray(double *Array1,double *Array2,double *Temp,unsigned long ArraySize)
    {
       asm {
           //Convert array size to DWORDs
           mov    eax,[ArraySize]
           shr      eax,2
             
           push   ds
    
           //Copy Array1 to temp - 32 bit copy - copies DWORDs
           lds      esi,[Array1]
           les      edi,[Temp]
           mov    ecx,eax
           rep     movsd
    
           //Copy Array2 to Array1
           lds      esi,[Array2]
           les      edi,[Array1]
           mov    ecx,eax
           rep     movsd
          
           //Copy Temp to Array2
           lds     esi,[Temp]
           les     edi,[Array2]
           mov   ecx,eax
           rep    movsd
    
           //Clean up
           pop    ds
       }
    }
    But this is still a huge copy process. Each movsd only gets half of the actual value since doubles are 64-bits. But this code should be nearly twice as fast as a memcpy.

    I did not use a temporary variable for the ArraySize because MSVC will undo stack protection when using temporary's and will cause the code to be slower. I used the eax register to store the size of ArraySize in DWORDs which should be faster than using the stack.

    I'm fairly sure this will copy all of the data - if your ArraySize is specified in total bytes - note that 1 double 8 bytes, and movsd only moves 4 bytes at a time. On a 64-bit system you could do a movsq but we can't afford those right now.

    I could construct a 64-bit copy using MMX, but MMX cannot transfer from memory to memory so it might actually be slower.
    Last edited by VirtualAce; 12-16-2003 at 04:07 PM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 16
    Last Post: 05-29-2009, 07:25 PM
  2. sorting number
    By Leslie in forum C Programming
    Replies: 8
    Last Post: 05-20-2009, 04:23 AM
  3. from 2D array to 1D array
    By cfdprogrammer in forum C Programming
    Replies: 17
    Last Post: 03-24-2009, 10:33 AM
  4. Class Template Trouble
    By pliang in forum C++ Programming
    Replies: 4
    Last Post: 04-21-2005, 04:15 AM
  5. Quick question about SIGSEGV
    By Cikotic in forum C Programming
    Replies: 30
    Last Post: 07-01-2004, 07:48 PM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21