jmh jmh - 3 months ago 9
C Question

Trying to swap the elements of a two dimensional array in C

I am writing a method that swaps the elements of a two dimensional array. I have looked for answers to this, but there don't seem to be many good answers for this kind of swapping. The main difference from traditional swapping is that I am not trying to swap the integers within one of the length 2 array but instead trying to swap a pair of the length 2 arrays, more specifically their pointers. I am pretty new to C (trying to switch from Java). When I compile the code below, I receive a warning "assignment makes integer from pointer without a cast". Any help would be greatly appreciated. Thanks in advance.

void swap(int array[][2], int indexA, int indexB)
{
int *temp = array[indexA];
*array[indexA] = array[indexB];
*array[indexB] = temp;
}


Edit: I also tried the code below to replace the last two lines (not including the brackets, but that caused the compiler to give the error "incompatible types when assigning to type ‘int[2]’ from type ‘int *’" for each of those lines.

array[indexA] = array[indexB];
array[indexB] = temp;


Edit: The array declaration is below and the the swap function gets called as part of a quicksort implementation. The sort method that is calling the swap method uses the same type of argument declaration as the one I used in swap (i.e. "int array[][2]).

int counts[256][2];

Answer

Your code is attempting to value-assign two-element arrays, which is not allowed (for two element arrays, or any other length fr that matter) unless they're buried in a structure.

To move your data you have several options. Keeping your existing prototype you can do the following:

void swap(int array[][2], int indexA, int indexB)
{
    int temp[2];
    memcpy(temp, array[indexA], sizeof(temp));
    memcpy(array[indexA], array[indexB], sizeof(array[indexA]));
    memcpy(array[indexB], temp, array[indexB]);
}

Alternatively, you can use an element loop:

void swap(int array[][2], int indexA, int indexB)
{
    for (size_t i=0;sizeof(array[0])/sizeof(array[0][0]);++i)
    {
        int temp = array[indexA][i];
        array[indexA][i] = array[indexB][i];
        array[indexB][i] = temp;
    }
}

Finally, you may also consider using something like this:

void swap(int (*a)[2], int (*b)[2])
{
    int temp[sizeof(*a)/sizeof((*a)[0])];
    memcpy(temp,a,sizeof(temp));
    memcpy(a,b,sizeof(*a));
    memcpy(b,temp,sizeof(*b));
}

And invoking it on your caller side like this:

swap(counts[indexA], counts[indexB]);

which is more readable IMHO. Sample follows:

#include <stdio.h>
#include <stdlib.h>

void swap(int (*a)[2], int (*b)[2])
{
    int temp[sizeof(*a)/sizeof((*a)[0])];
    memcpy(temp,a,sizeof(temp));
    memcpy(a,b,sizeof(*a));
    memcpy(b,temp,sizeof(*b));
}

int main(int argc, char *argv[])
{
    int counts[10][2];
    int indexA = 1, indexB = 2;
    counts[indexA][0] = counts[indexA][1] = 1;
    counts[indexB][0] = counts[indexB][1] = 2;
    swap(counts[indexA], counts[indexB]);

    // better be 2 2
    printf("%d %d\n", counts[indexA][0], counts[indexA][1]);
    return 0;
}

Output

2 2
Comments