Consider the C code below and the box-circle diagram to the right, which illustrates the situation at point 1. Assume stack memory allocation for nested scopes is used (which means that memory for variables in a scope is allocated on the stack and deallocated when the scope is exited).
1.1 m1
X
ext
m2
y
m11
m3
Z
m12
[o]e a[1] a[2]
m8
m9
m10
m7
p1
m4
a next
m7.1 m7
p2
m5
p3
me
struct T{ int *a; struct T* next; };
int**2; struct T X; struct T* p1; struct T* p2; struct T**p3;
int main() {
p1 = (struct T*) malloc(sizeof(struct T));
p2 = &X;
y = (int*) malloc(sizeof(int));
{
int* a[3];
a[1] = (int*) malloc(sizeof(int));
z = &a[1];
X.a = *z; // point 1
*p1.a = *z; // point 2
}
*p1.next = p1; // point 3
p2 = p1; // point 4
p3 = &p1; // point 5
d = // point 6
p3 = &*p3; // point 7
X.a = y; // point s
z = X.a; // point 9
free(X.a); // point 18
}
At point 2, there is an arrow from location m7.1 to location