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.
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.