Tutorial :How do I modify a pointer that has been passed into a function in C?



Question:

So, I have some code, kind of like the following, to add a struct to a list of structs:

void barPush(BarList * list,Bar * bar)  {      // if there is no move to add, then we are done      if (bar == NULL) return;//EMPTY_LIST;        // allocate space for the new node      BarList * newNode = malloc(sizeof(BarList));        // assign the right values      newNode->val = bar;      newNode->nextBar = list;        // and set list to be equal to the new head of the list      list = newNode; // This line works, but list only changes inside of this function  }  

These structures are defined as follows:

typedef struct Bar  {      // this isn't too important  } Bar;    #define EMPTY_LIST NULL    typedef struct BarList  {      Bar * val;      struct  BarList * nextBar;  } BarList;  

and then in another file I do something like the following:

BarList * l;    l = EMPTY_LIST;  barPush(l,&b1); // b1 and b2 are just Bar's  barPush(l,&b2);  

However, after this, l still points to EMPTY_LIST, not the modified version created inside of barPush. Do I have to pass list in as a pointer to a pointer if I want to modify it, or is there some other dark incantation required?


Solution:1

You need to pass in a pointer to a pointer if you want to do this.

void barPush(BarList ** list,Bar * bar)  {      if (list == NULL) return; // need to pass in the pointer to your pointer to your list.        // if there is no move to add, then we are done      if (bar == NULL) return;        // allocate space for the new node      BarList * newNode = malloc(sizeof(BarList));        // assign the right values      newNode->val = bar;      newNode->nextBar = *list;        // and set the contents of the pointer to the pointer to the head of the list       // (ie: the pointer the the head of the list) to the new node.      *list = newNode;   }  

Then use it like this:

BarList * l;    l = EMPTY_LIST;  barPush(&l,&b1); // b1 and b2 are just Bar's  barPush(&l,&b2);  

Jonathan Leffler suggested returning the new head of the list in the comments:

BarList *barPush(BarList *list,Bar *bar)  {      // if there is no move to add, then we are done - return unmodified list.      if (bar == NULL) return list;          // allocate space for the new node      BarList * newNode = malloc(sizeof(BarList));        // assign the right values      newNode->val = bar;      newNode->nextBar = list;        // return the new head of the list.      return newNode;   }  

Usage becomes:

BarList * l;    l = EMPTY_LIST;  l = barPush(l,&b1); // b1 and b2 are just Bar's  l = barPush(l,&b2);  


Solution:2

Generic answer: Pass a pointer to the thing you want to change.

In this case, it would be a pointer to the pointer you want to change.


Solution:3

Remember, in C, EVERYTHING is passed by value.

You pass in a pointer to a pointer, like this

int myFunction(int** param1, int** param2) {    // now I can change the ACTUAL pointer - kind of like passing a pointer by reference     }  


Solution:4

Yes, you have to pass in a pointer to the pointer. C passes arguments by value, not by reference.


Solution:5

This is a classic problem. Either return the allocated node or use a pointer of pointer. In C, you should pass a pointer to a X to a function where you want your X to be modified. In this case, since you want a pointer to be modified, you ought to pass a pointer to a pointer.


Note:If u also have question or solution just comment us below or mail us on toontricks1994@gmail.com
Previous
Next Post »