Como faço para modificar um ponteiro que foi passado para uma function em C?

Então, eu tenho algum código, como o seguinte, para adicionar uma estrutura a uma lista de estruturas:

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 } 

Essas estruturas são definidas da seguinte maneira:

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

e então em outro arquivo eu faço algo como o seguinte:

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

No entanto, depois disso, eu ainda aponto para EMPTY_LIST, não a versão modificada criada dentro do barPush. Eu tenho que passar a lista como um ponteiro para um ponteiro se eu quiser modificá-lo, ou há algum outro encantamento escuro necessário?

Você precisa passar um ponteiro para um ponteiro se quiser fazer isso.

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

Então use-o assim:

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

Jonathan Leffler sugeriu devolver o novo chefe da lista nos comentários:

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

Uso se torna:

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

Resposta genérica: passe um ponteiro para a coisa que você deseja alterar.

Nesse caso, seria um ponteiro para o ponteiro que você deseja alterar.

Lembre-se, em C, TUDO é passado por valor.

Você passa um ponteiro para um ponteiro, como este

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

Sim, você precisa passar um ponteiro para o ponteiro. C transmite argumentos por valor, não por referência.

Este é um problema clássico. Retornar o nó alocado ou usar um ponteiro de ponteiro. Em C, você deve passar um ponteiro para um X para uma function onde você deseja que seu X seja modificado. Nesse caso, desde que você deseja que um ponteiro seja modificado, você deve passar um ponteiro para um ponteiro.