Doubt with C pointers

2

I have a linked list, with a single variable that is the date (int). I made this function to delete by value.

lista *head = NULL;

void deletar(int valor) {

    lista *prev, *temp = head;
    if(temp->data == valor) {
        head = temp->prox;
        free(temp);
    } else {
        while(temp->data != valor && temp != NULL) {
            prev = temp;
            temp = temp->prox;
        }
        prev->prox = temp->prox;
        free(temp);
    }
}

But I do not understand why when I change:  % by% by% by% It does not work properly, since prev->prox = temp->prox; and temp = temp->prox; , have the same memory address. Address: 0x14d3050 and 0x14d3050

    
asked by anonymous 23.05.2017 / 18:16

1 answer

1

prev and temp are pointers. That is, they are variables, which live in their own memory address, whose value is an address to another place in memory.

int x = 5; // variável com o valor 5
int *y = &x; // variável cujo valor é o endereço de memória da variável x
*y = 6; // Atribui o valor 6 no endereço de memória armazenado em y.
        // ou seja, a x. 

prev->prox is equivalent to (*prev).prox . In prev->prox = temp->prox; you're saying:

  • Get the value stored in the memory location pointed to by prev
  • This value is a struct which, among other things, has a memory address called prox
  • Assign to prox the memory address that is in (*temp).prox
  • Visually

    Initial status:

    -- [ prev ] -- [ elemento a excluir ] -- [ prox ]
                              ^
                             temp
    

    Final status:

    -- [ prev ] -- [ prox ]
    
    temp > [ elemento a excluir ] 
    

    That is, the previous node will point to the next of temp . Which means that the original list will skip the node for which temp is pointing. You then release the memory area to which temp points on the next line and temp is out of scope.

    Already in temp = temp->prox; you are making temp point to your next element. In this case you are changing the address to which the temp variable is pointing. It would be the equivalent to do:

    int z = 6;
    y = &z;
    

    See that x in this case remains 5. You changed the address to which y points and not x content.

    Likewise, nothing happens to prev->prox because you have changed the address to which temp points. prev->prox is still pointing to the node address you were trying to delete.

    And the worst: temp is now pointing to the next element (just after the element you intended to delete):

    On the next line you are calling free(temp) . In this case:

  • You are releasing memory from the wrong element address
  • [elemento a excluir]->prox points to an area of memory that you have released.
  • Visually

    Initial status:

    -- [ prev ] -- [ elemento a excluir ] -- [ prox ]
                                                ^
                                               temp
    

    Final status:

    -- [ prev ] -- [ elemento que deveria ter sido excluido ] --                                     
    23.05.2017 / 19:20