1

I want to swap two rows of a 2d array defined as bellow.

    double (*mat)[N];
    mat = (double(*)[N])malloc(m*sizeof(double [N]));
    ...
    swap(mat, mat+1); 

But my swap(mat, mat+1); only swaps the first element in each row.

void swap(double **a,double **b){
    double *temp;
    temp = *a;
    *a = *b;
    *b = temp;
}

The same swap works if I use it one a 2D array defined double **mat; with dinamically allocated lines and rows.

1
  • Don't use double pointers. Commented May 7, 2020 at 17:19

2 Answers 2

0

You are correct -- you must pass pointer-to-pointer to int as the parameters to your swap function. Why? You want to change the pointers themselves. Passing a simple pointer, the function would receive a copy and any changes would be lost on return.

The key here is you cannot swap rows in your allocated collection directly without using memcpy to actually swap the data. Why? the rows are contained within a sequential block of memory you just allocated. You can simply declare an array-of-pointers to the beginning of each row in your allocated collection of data and then swap pointers within the array-of-pointers, e.g.

#define MAXI 10
...

    int (*a)[MAXI] = calloc (MAXI, sizeof *a),      /* pointer to array  */
        *p[MAXI];                                   /* array of pointers */

    for (int i = 0; i < MAXI; i++) {                /* loop */
        *a[i] = i, a[i][MAXI-1] = i;                /* set first/last each row */
        p[i] = a[i];                                /* set pointer to each row */
    }

Now you can swap the pointers with a function taking parameters of pointer-to-pointer, e.g.

void swpptr (int **a, int **b)                      /* swap pointers */
{
    void *tmp = *a;
    *a = *b;
    *b = tmp;
}

with, e.g.:

    puts ("\nswapping every other row...");
    for (int i = 1; i < MAXI; i+=2)                 /* loop */
        swpptr (&p[i-1], &p[i]);                    /* swap every other row */

A short example would be:

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

#define MAXI 10

void swpptr (int **a, int **b)                      /* swap pointers */
{
    void *tmp = *a;
    *a = *b;
    *b = tmp;
}

void prn_ptr2ptr (int **p, int n)                   /* print n int per-pointer */
{
    for (int i = 0; i < MAXI; i++) {
        for (int j = 0; j < n; j++)
            printf (" %d", p[i][j]);
        putchar ('\n');
    }
}

int main (void) {

    int (*a)[MAXI] = calloc (MAXI, sizeof *a),      /* pointer to array  */
        *p[MAXI];                                   /* array of pointers */

    for (int i = 0; i < MAXI; i++) {                /* loop */
        *a[i] = i, a[i][MAXI-1] = i;                /* set first/last each row */
        p[i] = a[i];                                /* set pointer to each row */
    }

    puts ("pre-swap:");                             /* ouput pre-swap pointers */
    prn_ptr2ptr (p, MAXI);

    puts ("\nswapping every other row...");
    for (int i = 1; i < MAXI; i+=2)                 /* loop */
        swpptr (&p[i-1], &p[i]);                    /* swap every other row */

    puts ("\npost-swap:");                          /* output post-swap pointers */
    prn_ptr2ptr (p, MAXI);
}

Example Use/Output

$ ./bin/ptr2arrayswap
pre-swap:
 0 0 0 0 0 0 0 0 0 0
 1 0 0 0 0 0 0 0 0 1
 2 0 0 0 0 0 0 0 0 2
 3 0 0 0 0 0 0 0 0 3
 4 0 0 0 0 0 0 0 0 4
 5 0 0 0 0 0 0 0 0 5
 6 0 0 0 0 0 0 0 0 6
 7 0 0 0 0 0 0 0 0 7
 8 0 0 0 0 0 0 0 0 8
 9 0 0 0 0 0 0 0 0 9

swapping every other row...

post-swap:
 1 0 0 0 0 0 0 0 0 1
 0 0 0 0 0 0 0 0 0 0
 3 0 0 0 0 0 0 0 0 3
 2 0 0 0 0 0 0 0 0 2
 5 0 0 0 0 0 0 0 0 5
 4 0 0 0 0 0 0 0 0 4
 7 0 0 0 0 0 0 0 0 7
 6 0 0 0 0 0 0 0 0 6
 9 0 0 0 0 0 0 0 0 9
 8 0 0 0 0 0 0 0 0 8

Look things over and let me know if you have any questions.

Sign up to request clarification or add additional context in comments.

Comments

0
void swap(double **a,double **b)

It works because, in this case, you swap the pointer. But when you declare:

double (*mat)[N];

It is a pointer to array. it's reason why it just swaps the first value of each row.

If you want to swap two arrays, just use pointer (do not use double pointer):

void swap( double *m1, double *m2, size_t n )
{
    for ( size_t i = 0; i < n; i++ )
    {
        double tmp = m1[i];
        m1[i] = m2[i];
        m2[i] = tmp;
    }
}

Then when you want to swap two rows:

swap(mat[0], mat[1], N);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.