Title: CS 241 Section Week
1CS 241 Section Week 2(09/04/08)
2Topics This Section
- More C basics
- Strings
- Functions
- Structures
- Memory
3Simple Example
include ltstdio.hgt void main(void)
printf(Hello World. \n \t and you ! \n ) /
print out a message / return Hello
World. and you !
4Summarizing the Example
- include ltstdio.hgt include header file stdio.h
- No semicolon at end
- Small letters only C is case-sensitive
- void main(void) is the only code executed
- printf( / message you want printed / )
- \n newline \t tab
- Dessert \ in front of other special characters
within printf. - printf(Have you heard of \The Rock\ ? \n)
5Type conversion
include ltstdio.hgt void main(void) int i,j
12 / i not initialized, only j / float
f1,f2 1.2 i (int) f2 / explicit i
lt- 1, 0.2 lost / f1 i /
implicit f1 lt- 1.0 / f1 f2 (int) j /
explicit f1 lt- 1.2 12.0 / f1 f2 j
/ implicit f1 lt- 1.2 12.0 /
- Explicit conversion rules for arithmetic
operation xyz - convert y or z as
- double lt- float lt- int lt- char, short
- then type cast it to x s type
- Moral stick with explicit conversions - no
confusion !
6Strings
7Review of strings
- Sequence of zero or more characters, terminated
by NUL (literally, the integer value 0) - NUL terminates a string, but isnt part of it
- important for strlen() length doesnt include
the NUL - Strings are accessed through pointers/array names
- include ltstring.hgt at program start
8String literals
- Evaluating ?dog? results in memory allocated for
three characters 'd ', ' o ', ' g ', plus
terminating NUL - char m ?dog?
- Note If m is an array name, subtle difference
- char m10 ?dog?
9String literals
- Evaluating ?dog? results in memory allocated for
three characters 'd ', ' o ', ' g ', plus
terminating NUL - char m ?dog?
- Note If m is an array name, subtle difference
- char m10 ?dog?
10 bytes are allocated for this array
10String literals
- Evaluating ?dog? results in memory allocated for
three characters 'd ', ' o ', ' g ', plus
terminating NUL - char m ?dog?
- Note If m is an array name, subtle difference
- char m10 ?dog?
10 bytes are allocated for this array
This is not a string literal Its an array
initializer in disguise! Equivalent to
'd','o','g','\0'
11String manipulation functions
- Read some source string(s), possibly write to
some destination location - char strcpy(char dst, char const src)
- char strcat (char dst, char const src)
- Programmers responsibility to ensure that
- destination region large enough to hold result
- source, destination regions dont overlap
- undefined behavior in this case
- according to C spec, anything could happen!
- char m10 ?dog?
- strcpy(m1, m)
12String manipulation functions
- Read some source string(s), possibly write to
some destination location - char strcpy(char dst, char const src)
- char strcat (char dst, char const src)
- Programmers responsibility to ensure that
- destination region large enough to hold result
- source, destination regions dont overlap
- undefined behavior in this case
- according to C spec, anything could happen!
- char m10 ?dog?
- strcpy(m1, m)
Assuming that the implementation of strcpy starts
copying left-to-right without checking for the
presence of a terminating NUL first, what will
happen?
13strlen() and size_t
- size_t strlen(char const string)
- / returns length of string /
- size_t is an unsigned integer type, used to
define sizes of strings and (other) memory blocks - Reasonable to think of size as unsigned...
- But beware! Expressions involving strlen() may be
unsigned (perhaps unexpectedly) - if (strlen(x) strlen(y) gt 0) ...
- avoid by casting
- ((int) (strlen(x) strlen(y)) gt 0)
- Problem what if x or y is a very large string?
- a better alternative (strlen(x) gt strlen(y))
14strlen() and size_t
- size_t strlen(char const string)
- / returns length of string /
- size_t is an unsigned integer type, used to
define sizes of strings and (other) memory blocks - Reasonable to think of size as unsigned...
- But beware! Expressions involving strlen() may be
unsigned (perhaps unexpectedly) - if (strlen(x) strlen(y) gt 0) ...
- avoid by casting
- ((int) (strlen(x)) strlen(y) gt 0)
- Problem what if x or y is a very large string?
- a better alternative (strlen(x) gt strlen(y))
always true!
15strcmp() string comparison
- int strcmp(char const s1, char const s2)
- returns a value less than zero if s1 precedes s2
in lexicographical order - returns zero if s1 and s2 are equal
- returns a value greater than zero if s1 follows
s2. - Source of a common mistake
- seems reasonable to assume that strcmp returns
true (nonzero) if s1 and s2 are equal false
(zero) otherwise - In fact, exactly the opposite is the case!
16Restricted vs. unrestricted string functions
- Restricted versions require an extra integer
argument that bounds the operation - char strncpy(char dst, char const src, size_t
len) - char strncat(char dst, char const src, size_t
len) - int strncmp(char const s1, char const s2,
size_t len) - safer in that they avoid problems with missing
NUL terminators - safety concern with strncpy
- If bound isnt large enough, terminating NUL
wont be written - Safe alternative
- strncpy(buffer, name, BSIZE)
- bufferBSIZE-1 '\0'
17String searching
- char strstr(const char haystack, const char
needle) - / return a pointer to first occurrence of the
substring needle in the string haystack. or NULL
if the substring is not found /
18Functions
19Functions basic example
include ltstdio.hgt int sum(int a, int b) /
function prototype at start of file / void
main(void) int total sum(4,5) / call to
the function / printf(The sum of 4 and 5 is
d, total) int sum(int a, int b) / the
function itself - arguments passed by
value/ return (ab) / return by value
/
20Argument Passing
21Whats wrong with this ?
include ltstdio.hgt void dosomething(int
ptr) main() int p dosomething(p) printf(
d, p) / will this work ? / void
dosomething(int ptr) / passed and returned by
reference / int temp3212 ptr
(temp) / compiles correctly, but gives
run-time error /
22Passing and returning arrays
include ltstdio.hgt void init_array(int array,
int size) void main(void) int list5
init_array(list, 5) for (i 0 i lt 5 i)
printf(nextd, arrayi) void
init_array(int array, int size) / why size ?
/ / arrays ALWAYS passed by reference /
int i for (i 0 i lt size i) arrayi
0
23Structures
24Structures
- Equivalent of Javas classes with only data (no
methods)
include ltstdio.hgt struct birthday int
month int day int year main()
struct birthday mybday / - no new needed !
/ / then, its just like Java ! /
mybday.day1 mybday.month1 mybday.year1977
printf(I was born on d/d/d, birth.day,
birth.month, birth.year)
25More on Structures
struct person char name41 int age
float height struct / embedded
structure / int month int day
int year birth struct person me
me.birth.year1977 struct person class60
/ array of info about everyone in class
/ class0.nameGun class0.birth.year1971
26Passing/Returning a structure
/ pass struct by value / void
display_year_1(struct birthday mybday)
printf(I was born in d\n, mybday.year) /
- inefficient why ? / . . . . / pass struct
by reference / void display_year_2(struct
birthday pmybday) printf(I was born in
d\n, pmybday-gtyear) / warning ! -gt, not
., after a struct pointer/ . . . . /
return struct by value / struct birthday
get_bday(void) struct birthday newbday
newbday.year1971 / . after a struct /
return newbday / - also inefficient why ?
/
27Synonym for a data type
typedef int Employees Employees my_company /
same as int my_company / typedef struct person
Person Person me / same as struct
person me / typedef struct person
Personptr Personptr ptrtome / same as
struct person ptrtome/
- Easier to remember
- Clean code
28More pointers
int month12 / month is a pointer to base
address 430/ month3 7 / month address
3 int elements gt int at address (43034)
is now 7 / ptr month 2 / ptr points to
month2, gt ptr is now (4302 int
elements) 438 / ptr5 12 / ptr
address 5 int elements gt int at
address (43454) is now 12. Thus, month7 is
now 12 / ptr / ptr lt- 438 1
size of int 442 / (ptr 4)2 12 /
accessing ptr6 i.e., array9 /
- Now , month6, (month6), (month4)2,
ptr3, (ptr3) are all the same integer
variable.
29Memory Layout
- How is memory organized?
- Textcode, constant data
30Memory Layout
- How is memory organized?
- Textcode, constant data
- Data initialized global and static variables
31Memory Layout
- How is memory organized?
- Textcode, constant data
- Data initialized global and static variables
- BSS (Block Started by Symbol)
32Memory Layout
- How is memory organized?
- Textcode, constant data
- Data initialized global and static variables
- BSS (Block Started by Symbol)
- Heap dynamic memory
33Memory Layout
- How is memory organized?
- Textcode, constant data
- Data initialized global and static variables
- BSS (Block Started by Symbol)
- Heap dynamic memory
- Stack local variables
34Memory Layout
35Overview of memory management
- Stack-allocated memory
- When a function is called, memory is allocated
for all of its parameters and local variables. - Each active function call has memory on the stack
(with the current function call on top) - When a function call terminates,
- the memory is deallocated (freed up)
- Ex main() calls f(),
- f() calls g()
- g() recursively calls g()
g()
g()
f()
main()
36Memory Allocation
- How is memory allocated?
- Global and static variables program startup
37Memory Allocation
- How is memory allocated?
- Global and static variables program startup
- Local variables function call
38Memory Allocation
- How is memory allocated?
- Global and static variables program startup
- Local variables function call
- Dynamic memory malloc()
39Memory Allocation
40- Heap-allocated memory
- This is used for persistent data, that must
survive beyond the lifetime of a function call - dynamically allocated memory C statements can
create new heap data (similar to new in Java/C) - Heap memory is allocated in a more complex way
than stack memory - Like stack-allocated memory, the underlying
system determines where to get more memory the
programmer doesnt have to search for free memory
space!
41Allocating new heap memory
Note void denotes a generic pointer type
- void malloc(size_t size)
- Allocate a block of size bytes,
- return a pointer to the block
- (NULL if unable to allocate block)
42Memory deallocation
- How is memory deallocated?
- Global and static variables program finish
43Memory deallocation
- How is memory deallocated?
- Global and static variables program finish
- Local variables function return
44Memory deallocation
- How is memory deallocated?
- Global and static variables program finish
- Local variables function return
- Dynamic memory free()
45Memory deallocation
- How is memory deallocated?
- Global and static variables program finish
- Local variables function return
- Dynamic memory free()
- All memory is deallocated at
- program termination
46Memory deallocation
- How is memory deallocated?
- Global and static variables program finish
- Local variables function return
- Dynamic memory free()
- All memory is deallocated at
- program termination
- It is good style to free allocated
- memory anyway
47Memory deallocation
48Deallocating heap memory
- void free(void pointer)
- Given a pointer to previously allocated memory,
- put the region back in the heap of unallocated
memory - Note easy to forget to free memory when no
longer needed... - especially if youre used to a language with
garbage collection like Java - This is the source of the notorious memory leak
problem - Difficult to trace the program will run fine
for some time, until suddenly there is no more
memory!
49Checking for successful allocation
- Call to malloc might fail to allocate memory, if
theres not enough available - Easy to forget this check, annoying to have to do
it every time malloc is called...
50Memory errors
- Using memory that you have not initialized
- Using memory that you do not own
- Using more memory than you have allocated
- Using faulty heap memory management
51Using memory that you have not initialized
- Uninitialized memory read
- Uninitialized memory copy
- not necessarily critical unless a memory read
follows - void foo(int pi)
- int j
- pi j
- / UMC j is uninitialized, copied into pi /
-
- void bar()
- int i10
- foo(i)
- printf("i d\n", i)
- / UMR Using i, which is now junk value /
52Using memory that you dont own
- Null pointer read/write
- typedef struct node
- struct node next
- int val
- Node
- int findLastNodeValue(Node head)
- while (head-gtnext ! NULL) / Expect NPR /
- head head-gtnext
-
- return head-gtval / Expect ZPR /
What if head is NULL?
53Using memory that you dont own
- Invalid pointer read/write
- Pointer to memory that hasnt been allocated to
program - void genIPR()
- int ipr (int ) malloc(4 sizeof(int))
- int i, j
- i (ipr - 1000) j (ipr 1000) / Expect
IPR / - free(ipr)
-
- void genIPW()
- int ipw (int ) malloc(5 sizeof(int))
- (ipw - 1000) 0 (ipw 1000) 0 / Expect
IPW / - free(ipw)
54Using memory that you havent allocated
- Array bound read/write
- void genABRandABW()
- const char name Safety Critical"
- char str (char) malloc(10)
- strncpy(str, name, 10)
- str11 '\0' / Expect ABW /
- printf("s\n", str) / Expect ABR /
55Faulty heap management
- Memory leak
- int pi
- void foo()
- pi (int) malloc(8sizeof(int))
- / Allocate memory for pi /
- / Oops, leaked the old memory pointed to by pi
/ -
- free(pi) / foo() is done with pi, so free it
/ -
- void main()
- pi (int) malloc(4sizeof(int))
- / Expect MLK foo leaks it /
- foo()
56Faulty heap management
- Potential memory leak
- no pointer to the beginning of a block
- not necessarily critical block beginning may
still be reachable via pointer arithmetic - int plk NULL
- void genPLK()
- plk (int ) malloc(2 sizeof(int))
- / Expect PLK as pointer variable is
incremented - past beginning of block /
- plk
57Faulty heap management
- Freeing non-heap memory
- Freeing unallocated memory
- void genFNH()
- int fnh 0
- free(fnh) / Expect FNH freeing stack memory
/ -
- void genFUM()
- int fum (int ) malloc(4 sizeof(int))
- free(fum1) / Expect FUM fum1 points to
middle of a block / - free(fum)
- free(fum) / Expect FUM freeing already freed
memory /
58Dynamic Memory
59Dynamic Memory
60Dynamic Memory
61Dynamic Memory
62Dynamic Memory
63Dynamic Memory
64Dynamic Memory
65Dynamic Memory
66Dynamic Memory
67Dynamic Memory
68Dynamic Memory
69Before you go.
- Always initialize anything before using it
(especially pointers) - Dont use pointers after freeing them
- Dont return a functions local variables by
reference - No exceptions so check for errors everywhere
- An array is also a pointer, but its value is
immutable. - Many things I havent told you you should be
comfortable enough now to read them up by
yourself.
70Dynamic Memory
- Code Execution start with dog()
- Memory
char cat(char x, int i) static int r
4 x3 'h' char result (char
)malloc(20) sprintf(result, "s x d", x,
i) return result void dog() char
s "my cat" int z 12 cat(s, z)
71Dynamic Memory
char cat(char x, int i) static int r
4 x3 'h' char result (char
)malloc(20) sprintf(result, "s x d", x,
i) return result void dog() char
s "my cat" int z 12 cat(s, z)
72Dynamic Memory
char cat(char x, int i) static int r
4 x3 'h' char result (char
)malloc(20) sprintf(result, "s x d", x,
i) return result void dog() char
s "my cat" int z 12 cat(s, z)
my cat
s
73Dynamic Memory
char cat(char x, int i) static int r
4 x3 'h' char result (char
)malloc(20) sprintf(result, "s x d", x,
i) return result void dog() char
s "my cat" int z 12 cat(s, z)
z 12
my cat
s
74Dynamic Memory
char cat(char x, int i) static int r
4 x3 'h' char result (char
)malloc(20) sprintf(result, "s x d", x,
i) return result void dog() char
s "my cat" int z 12 cat(s, z)
i 12
cat() Stack Frame
x
z 12
dog() Stack Frame
my cat
s
75Dynamic Memory
char cat(char x, int i) static int r
4 x3 'h' char result (char
)malloc(20) sprintf(result, "s x d", x,
i) return result void dog() char
s "my cat" int z 12 cat(s, z)
i 12
cat() Stack Frame
x
z 12
dog() Stack Frame
my cat
s
r 4
Static Memory
76Dynamic Memory
char cat(char x, int i) static int r
4 x3 'h' char result (char
)malloc(20) sprintf(result, "s x d", x,
i) return result void dog() char
s "my cat" int z 12 cat(s, z)
i 12
cat() Stack Frame
x
z 12
dog() Stack Frame
my hat
s
r 4
Static Memory
77Dynamic Memory
char cat(char x, int i) static int r
4 x3 'h' char result (char
)malloc(20) sprintf(result, "s x d", x,
i) return result void dog() char
s "my cat" int z 12 cat(s, z)
20 bytes
Heap Memory
cat() Stack Frame
result
i 12
x
z 12
dog() Stack Frame
my hat
s
r 4
Static Memory
78Dynamic Memory
char cat(char x, int i) static int r
4 x3 'h' char result (char
)malloc(20) sprintf(result, "s x d", x,
i) return result void dog() char
s "my cat" int z 12 cat(s, z)
my hat x 12
Heap Memory
cat() Stack Frame
result
i 12
x
z 12
dog() Stack Frame
my hat
s
r 4
Static Memory
79Dynamic Memory
char cat(char x, int i) static int r
4 x3 'h' char result (char
)malloc(20) sprintf(result, "s x d", x,
i) return result void dog() char
s "my cat" int z 12 cat(s, z)
my hat x 12
Heap Memory
z 12
dog() Stack Frame
my hat
s
r 4
Static Memory