A trick question about C pointer. Read code snippet below and try explain why the list value changed (this question was based on this code):
tail has the memory address of list.
How is possible list be changed below?
typedef struct _node {
struct _node *next;
int value;
}Node;
int main(){
Node *list, *node, *tail;
int i = 100;
list = NULL;
printf("\nFirst . LIST value = %d", list);
tail =(Node *) &list;
node = malloc (sizeof (Node));
node->next = NULL;
node->value = i;
//tail in this point contains the memory address of list
tail->next = node;
printf("\nFinally. LIST value = %d", list);
printf("\nLIST->value = %d", (list->value));
return 0;
}
—- Output
First . List value = 0
why this values ??? im not expecting this …
Finally . LIST value = 16909060
LIST->value = 100
Let’s look at what happens to the memory in your program. You start with 3 local variables, all of type
Node*. At the moment they all point to garbage, as they have been declared but not initialised.An ascii art diagram of the memory might be (The layout is implementation dependant)
You then set list to
NULL, andtailto the address of node (casting away its type, a bad idea), giving youYou then malloc a new
Node, setting list to its address.You next try to set
tail->nextto node. You’ve said that you knowtailpoints to aNodewhen you did the typecast, so the compiler believes you. TheNodetail points to starts atlist‘s address, like soYou then set
tail->nexttonode, making bothlistandnodepoint to theliststructure.You’ve printed
listas a signed integer (“%d”). This is a bad idea – if you are using a 64 bit machine and have other arguments in the printf statement they may be clobbered, use the pointer format (“%p”) instead.list->valueis the same asnode->value, so it’s still going to be100.Pointers become easier if you think about how they actually are represented in the machine – as an index to a huge array which holds all of your data (modulo pointer sizes, virtual memory etc.).
Next time it might be easier just to use
list = node.