5

I have the following code which I want to make it so that board now has the value of new_board and vice versa. Since they are both pointers I thought I could just swap the addresses they point to. When I print in print2() the addresses are appropriately swapped. However, when I print in print1() the addresses have somehow swapped back, which doesn't make any sense to me. Further if I print out the values in the board at print2() they are also correct.

main(){
  char *new_board = (char *)malloc(sizeof(char) * rows * cols );
  char *board = (char *)malloc(sizeof(char) * rows * cols );
  update_board2(board, new_board, rows, cols);
  print1();
}

void update_board2(char *board, char *new_board, int rows, int cols){
  //do a bunch of stuff
  char *temp = board;
  board = new_board;
  new_board = temp;
  print2();
}
emschorsch
  • 1,619
  • 3
  • 19
  • 33
  • 4
    Pointers (like all other objects) are passed _by value_ in C. `update_board2` is operating of copies of the arguments passed. Also `new_board` and `board` are not declared as pointers. What compile errors and warnings are you getting? – CB Bailey Nov 06 '12 at 07:53
  • Sorry in my code they are, I miscopied. – emschorsch Nov 06 '12 at 08:00
  • 1
    Also, [don't cast the return value of malloc() in C](http://stackoverflow.com/a/605858/28169), and avoid `sizeof (char)` since it's just a very verbose 1. – unwind Nov 06 '12 at 08:39

3 Answers3

17

If you want to change the values of the pointers themselves, then the function update_board2 has to accept double pointers. Otherwise the pointers get copied within the function and you are swapping only these temporary copies rather than the real pointers the caller has passed:

void update_board2(char **board, char **new_board){
  char *temp = *board;
  *board = *new_board;
  *new_board = temp;
  print2();
}
Blagovest Buyukliev
  • 42,498
  • 14
  • 94
  • 130
  • who knew. That was pretty confusing glad I learned a new source of confounding bugs today. I guess the fact that the values switched as soon as the function returned should have been a give away that it was copied by value not reference. – emschorsch Nov 06 '12 at 08:10
9

You need to make the following change:

update_board2(&board, &new_board, rows, cols);

void update_board2(char **board, char **new_board, int rows, int cols){
  //do a bunch of stuff
  char *temp = *board;
  *board = *new_board;
  *new_board = temp;
  print2();
}

In this case pointers will be swapped correctly.

Alex
  • 9,891
  • 11
  • 53
  • 87
3

your main needs to be fixed too

i.e.

char * new_board = (char *)malloc(sizeof(char) * rows * cols );
char * board = (char *)malloc(sizeof(char) * rows * cols );

malloc returns a pointer, not a character.

fkl
  • 5,412
  • 4
  • 28
  • 68