C and Data Structures Baojian Hua bjhua@ustc.edu.cn Memory Layout C and Data Structures Baojian Hua bjhua@ustc.edu.cn
Goals of Today’s Lecture Behind the scenes of running a program Code, executable, and process Memory layout for UNIX processes, and relationship to C Explicit memory management in C malloc: allocate memory from the heap free: deallocate memory from the heap
From C Code to Process C source files Binary files Executables Process .c; .h Binary files .o Executables a.out Process Managed by OS C source code compiling binary files linking executable running process
Main Memory Network Audio CPU Disk Video Memory Data Bus Disk Video Memory shared by all processes
Virtual Memory Continuous memory space for all process each with its physical space pretends you the same virtual space 0xffffffff
Organization of Virtual Memory: .text Program code and constant binary form loaded libraries text 0xffffffff
Organization of Virtual Memory: .text Program code and constant binary form loaded libraries known as “text” segment space calculated at compile-time text 0xffffffff
Organization of Virtual Memory: .data Data: initialized global data in the program Ex: int size = 100; BSS: un-initialized global data in the program Ex: int length; text data bss 0xffffffff
Organization of Virtual Memory: heap Heap: dynamically-allocated spaces Ex: malloc, free OS knows nothing about it space content dynamically grows as program runs text data bss heap 0xffffffff
Organization of Virtual Memory: stack Stack: local variables in functions we’ll discuss stack soon support function call/return and recursive functions grow to low address text data bss heap stack 0xffffffff
Summary text: program text data: initialized globals & static data bss: un-initialized globals & static data heap: dynamically managed memory stack: function local variables text data bss heap stack 0xffffffff
Example char *string = “hello”; int iSize; char *f(int x) { char *p; p = malloc (iSize); return p; } text data bss heap stack 0xffffffff
Example char *string = “hello”; int iSize; char *f (int x) { char *p; p = malloc (iSize); return p; } text data bss heap stack 0xffffffff
Variable Lifetime text: data, bss: heap: stack: program startup program finish data, bss: heap: dynamically allocated de-allocated (free) stack: function call function return text data bss heap stack 0xffffffff
Example char *string = “hello”; program startup int iSize; char *f (int x) { char* p; iSize = 8; p = malloc (iSize); return p; } program startup text data bss when f() is called heap live after allocation; till free() or program finish stack 0xffffffff
Variable Initialization text: readonly data on program startup bss: un-initialized (though some systems initialize with 0) heap: un-initialized stack: text data bss heap stack 0xffffffff
Explicit Memory Management Heap management in C is explicit “malloc” to request a region “free” to recycle a region It’s the programmers’ responsibility to make sure that such a sequence of action is safe
Example int main() { int *p; p = malloc (4); *p = 99; return 0; } text text data bss heap p stack 0xffffffff
Example int main() { int *p; p = malloc (4); *p = 99; return 0; } text text data bss heap #@%*& p stack 0xffffffff
Example int main() { int *p; p = malloc (4); *p = 99; return 0; } text text data bss heap 99 p stack 0xffffffff
Example int main() { int *p; p = malloc (4); *p = 99; int *q; q = p; // alias return 0; } text data bss heap 99 q p stack 0xffffffff
Example int main() { int *p; p = malloc (4); *p = 99; int *q; q = p; printf (“%d\n”, *q); return 0; } text data bss heap 99 q p stack 0xffffffff
Example int main() { int *p; p = malloc (4); *p = 99; int *q; q = p; printf (“%d\n”, *q); free (q); return 0; } text data bss heap q p stack 0xffffffff
Dangling Pointer Reference int main() { int *p, *q; q = p = (int *) malloc (4); free (q); *p; return 0; }
Dangling Dereference int main() { int *p, *q; q = p = (int *) malloc (4); free (q); *p; return 0; } text data bss heap #@%*& p q stack 0xffffffff
Dangling Dereference int main() { int *p, *q; q = p = (int *) malloc (4); free (q); *p; return 0; } text data bss heap p q stack 0xffffffff
Dangling Dereference int main() { int *p, *q; q = p = (int *) malloc (4); free (q); *p; // no this memory!!! return 0; } text data bss heap p q stack 0xffffffff
Memory Leak int main() { int *p; p = (int *) malloc (4); // make the above space unreachable // even worse… while (1) p = malloc (4); return 0; }
Memory Leak void f (); void f () { int *p; p = malloc (4); return; } int main () f (); return 0;
Summary Dangling pointers and memory leak are evil sources of bugs: hard to debug may fire after a long time of run may far from the bug point hard to prevent especially by using the static methods Part of the reasons for the popularity of garbage collection