Reputation: 5184
For the following code compiled with gcc -Wall -pedantic -std=c99 -g bug.c
I see following strange result
#include<stdio.h>
#include<stdlib.h>
typedef struct node_ {
int key;
} node;
void
add (node** cur, node* n)
{
if(*cur)
{
printf("%p %p\n", (void *)*cur, (void *)n);
printf("%d %d\n", (*cur)->key, n->key);
}
*cur = n;
}
int
main()
{
node* previous = 0;
char k[] = {1, 2, 3};
/* add(&previous, &(node){k[0]}); */
/* add(&previous, &(node){k[1]}); */
/* add(&previous, &(node){k[2]}); */
/* puts(""); */
for(int i=0; i<3; ++i)
add(&previous, &(node){k[i]});
}
Results
% gcc --version
gcc (Ubuntu 4.9.2-0ubuntu1~14.04) 4.9.2
% ./a.out
0x7fff756d60f0 0x7fff756d60f0
2 2
0x7fff756d60f0 0x7fff756d60f0
3 3
With unrolled loop i see a correct behviour
0x7ffdae8c72d0 0x7ffdae8c72e0
1 2
0x7ffdae8c72e0 0x7ffdae8c72f0
2 3
Upvotes: 1
Views: 53
Reputation: 85877
for(int i=0; i<3; ++i)
add(&previous, &(node){k[i]});
This is equivalent to:
for(int i=0; i<3; ++i) {
node tmp = { k[i] };
add(&previous, &tmp);
}
Each time through the loop, a temporary node
struct is created, used, and destroyed again. After the first iteration, looking at *previous
is an error because it points to a variable that no longer exists.
This situation is equivalent to returning the address of a local variable from a function. (Except there's no separate function; we just leave a local block. But the principle is the same: We retain a pointer to a local variable after leaving its scope and ending its lifetime.)
Upvotes: 4