OS Lecture 02
OS Lecture 02
2
The Application of C Language
C is not a “very high level” language, nor a “big” one,
and is not specialized to any particular area of
application. But its absence of restrictions and its
generality make it more convenient and effective for
many tasks than supposedly more powerful
languages.
Kernighan and Ritchie
With C we can write programs that allow us to exploit
underlying features of the architecture
3
C Concepts
Compiler Creates usable programs from C source code
Typed variables Must declare the kind of data the variable will
contain
Typed functions Must declare the kind of data returned from the
function
Header files (.h) Allows declaring functions and variables in separate
files
Structs Groups of related values
Enums Lists of predefined values
Pointers Aliases to other variables
4
C Memory Layout
0x FFFF FFFF
Program’s address space contains Stack
4 regions:
Stack: local variables, grows
downward
Heap
Heap: space requested via malloc()
and used with pointers; resizes Static Data
dynamically, grows upward
Static Data: global and static
variables, does not grow or shrink Code
Code: loaded when program starts, Reserved
does not change 0x 0000 0000
OS prevents accesses between stack and heap (via virtual memory) 5
Where Do the Variables Go?
Declared outside a function:
#include <stdio.h>
Static Data
Declared inside a function: int varGlobal;
Stack
main() is a function int main() {
freed when the function returns int varLocal;
Dynamically allocated: int *varDyn =
malloc(sizeof(int));
Heap }
i.e. malloc (will be covered shortly)
6
Stack
Each stack frame is a contiguous block of memory holding the
local variables of a single function
A stack frame includes:
Location of caller function
Function arguments
Space for local variables
Stack pointer (SP) tells where lowest (current) stack frame is
When function ends, stack pointer is moved back (but data
remains (garbage!)); frees memory for future stack frames
7
Stack
Last In, First Out (LIFO) data structure
int main() {
a(0); main
return 1; Stack Pointer
}
void a(int m) {
b(1); a
} Stack Pointer
void b(int n) {
c(2); b
d(4);
} Stack Pointer
void c(int o) {
printf(“c”); d
}
void d(int p) { Stack Pointer
printf(“d”); 8
}
Stack Misuse
int *getPtr() {
int y;
y = 3; Never return pointers to local
return &y; variable from functions!
}
Your compiler will warn you about
int main () { this.
int *stackAddr, content;
stackAddr = getPtr(); Do not ignore such warnings!
content = *stackAddr;
printf("%d", content); /* 3 */
printf overwrites stack frames.
content = *stackAddr;
printf("%d", content); /* ? */
} 9
Static Data
Place for variables that persist
Data not subject to comings and goings like function calls
Examples: string literals, global variables
String literal example: char * str = “hi”;
Do not be mistaken with: char str[] = “hi”;
This will put str on the stack!
Size does not change, but sometimes data can
Notably string literals cannot
10
Code
Copy of your code goes there
C code becomes data too!
Does (should) not change
Typically read-only
11
Dynamic Memory Allocation
Want persisting memory (like static) even when we do
not know size at compile time?
e.g. input files, user interaction
Stack will not work because stack frames are not
persistent
Dynamically allocated memory goes on the Heap
more permanent than Stack
Need as much space as possible without interfering
with Stack
Start at opposite end and grow towards Stack
12
The sizeof Operator
If integer sizes are machine dependent, how do we tell?
Use sizeof() operator
Returns size in number of char-sized units of a variable or data
type name
Examples: int x; sizeof(x); sizeof(int);
sizeof(char) is always 1
Can we use sizeof to determine a length of an array?
Generally no but there is an exception:
int a[61];
sizeof(a) gets the total number of bytes stored in the array a.
To get the number of elements, use: sizeof(a) / sizeof(int)
This ONLY works for arrays defined on the stack IN THE SAME FUNCTION
It is not recommended to do this. A preferred way is to keep
track of an array size elsewhere. 13
Allocating Memory
Functions for requesting memory: malloc(), calloc(), and
realloc()
malloc(n)
Allocates a continuous block of n bytes of uninitialized memory
(contains garbage!)
Returns a pointer to the beginning of the allocated block; NULL
indicates failed request (check for this!)
Different blocks not necessarily adjacent
14
Any Questions?
15