Pergunta

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, 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, ainda aponta para o email_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?

Foi útil?

Solução

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

Em seguida, use 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; 
}

O uso se torna:

BarList * l;

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

Outras dicas

Resposta genérica: passe um ponteiro para o que você deseja mudar.

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

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

Você passa um ponteiro para um ponteiro, assim

int myFunction(int** param1, int** param2) {

// now I can change the ACTUAL pointer - kind of like passing a pointer by reference 

}

Sim, você tem que passar um ponteiro para o ponteiro. C passa argumentos por valor, não por referência.

Este é um problema clássico. Retorne o nó alocado ou use um ponteiro do ponteiro. Em C, você deve passar um ponteiro para um X para uma função em que deseja que seu X seja modificado. Nesse caso, como você deseja que um ponteiro seja modificado, você deve passar um ponteiro para um ponteiro.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top