¿Cómo modifico un puntero que se ha pasado a una función en C?

Entonces, tengo un código, como el siguiente, para agregar una estructura a una lista de estructuras:

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 } 

Estas estructuras se definen de la siguiente manera:

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

y luego en otro archivo hago algo como lo siguiente:

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

Sin embargo, después de esto, sigo señalando a EMPTY_LIST, no a la versión modificada creada dentro de barPush. ¿Tengo que pasar la lista como un puntero a un puntero si quiero modificarlo, o se necesita algún otro conjuro oscuro?

Necesita pasar un puntero a un puntero si desea hacer esto.

 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; } 

Entonces úsalo así:

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

Jonathan Leffler sugirió devolver el nuevo encabezado de la lista en los comentarios:

 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; } 

El uso se convierte en:

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

Respuesta genérica: Pase un puntero a la cosa que desea cambiar.

En este caso, sería un puntero al puntero que desea cambiar.

Recuerde, en C, TODO se pasa por valor.

Pasa un puntero a un puntero, como este

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

Sí, tienes que pasar un puntero al puntero. C pasa argumentos por valor, no por referencia.

Este es un problema clásico. Devuelva el nodo asignado o use un puntero de puntero. En C, debe pasar un puntero a una X a una función donde desea que se modifique su X. En este caso, dado que desea que se modifique un puntero, debe pasar un puntero a un puntero.