0

So I have the following function. The function takes a target int ** double pointer and copies a source array to it.

void copyMatrix(int ** target, int m, int n, int source[m][n])
{
  int i,j;

  target = (int **) malloc(m * sizeof(int *));
  for (i = 0; i < m; i++)
    target[i] = (int *)malloc(n * sizeof(int));

  for(i=0; i < m; i++){
    for(j=0; j < n; j++){
     target[i][j] = source[i][j];
    }
  }
  printf("%d ", target[i][j]);
}

When i call printf after the for loops, i get a segfault, but if i call printf inside the for loops, it prints target[i][j] correctly. Why is this? I'm tearing my hair out over this...

ahoang18
  • 143
  • 7
  • 2
    What do you expect the value of `i` and `j` to be outside the loop? – Naman Nov 21 '16 at 05:21
  • 4
    You'll need to pass the pointer to your `**target`, so it becomes `***target`. And then use `*target = ...` when allocating. You're currently trying to modify the (double) pointer itself, not the value it points to. –  Nov 21 '16 at 05:22
  • 1
    Also look into http://stackoverflow.com/a/7307699/1746118 – Naman Nov 21 '16 at 05:24
  • Though you should probably avoid possing triple dereferenced values. You can do it once as an excercise. Consider allocating `target` outside the `copyMatrix` function, or return it instead (and don't pass it). Since you have to free it outside the function as it's currently written, you better make `copyMatrix` behave like `malloc` and friends. –  Nov 21 '16 at 05:25
  • Thanks for all the comments everyone. i think i learned more in about thirty seconds than I ever have about pointers – ahoang18 Nov 21 '16 at 05:31
  • @Lundin i could swear it was c++. time for new glasses – n. m. could be an AI Nov 21 '16 at 11:23

2 Answers2

1

After the loops, i == m and j == n. They both point 1 item past the max. Arrays in C are zero-indexed, so accessing target[n][m] of an array with size [n][m] will give an out-of-bounds access.

Lundin
  • 195,001
  • 40
  • 254
  • 396
0

I am not clear as to why do you want to create an array of pointers first. With this approach, you end up having a problem of modifying the double pointer itself which will not reflect in the caller. You can simply alloc an array directly to store the input 2D array.

Your code:

void copyMatrix(int ** target, int m, int n, int source[m][n])
{
  int i,j;

  target = (int **) malloc(m * sizeof(int *));
  for (i = 0; i < m; i++)
    target[i] = (int *)malloc(n * sizeof(int));

  for(i=0; i < m; i++){
    for(j=0; j < n; j++){
     target[i][j] = source[i][j];
    }
  }
  printf("%d ", target[i][j]);
}

Modified Code:

void copyMatrix(int ** target, int m, int n, int source[m][n])
{
  int i,j;

  *target = (int *) malloc(sizeof(int) * (m * n));


  for(i=0; i < m; i++){
    for(j=0; j < n; j++){
     (*target)[i][j] = source[i][j];
    }
  }
  printf("%d ", (*target)[i][j]);
}
Jay
  • 24,173
  • 25
  • 93
  • 141