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