Presentation is loading. Please wait.

Presentation is loading. Please wait.

Topics This Section  More C basics  Strings  Functions  Structures  Memory.

Similar presentations


Presentation on theme: "Topics This Section  More C basics  Strings  Functions  Structures  Memory."— Presentation transcript:

1 Topics This Section  More C basics  Strings  Functions  Structures  Memory

2 Simple Example #include void main(void) { printf(“Hello World. \n \t and you ! \n ”); /* print out a message */ return; } $Hello World. and you ! $

3 Summarizing the Example  #include = 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”);

4 Type conversion #include void main(void) { int i,j = 12; /* i not initialized, only j */ float f1,f2 = 1.2; i = (int) f2; /* explicit: i <- 1, 0.2 lost */ f1 = i; /* implicit: f1 <- 1.0 */ f1 = f2 + (int) j; /* explicit: f1 <- 1.2 + 12.0 */ f1 = f2 + j; /* implicit: f1 <- 1.2 + 12.0 */ } Explicit conversion rules for arithmetic operation x=y+z; convert y or z as double <- float <- int <- char, short then type cast it to x ’s type Moral: stick with explicit conversions - no confusion !

5 Strings

6 Review of strings  Sequence of zero or more characters, terminated by NUL (literally, the integer value 0 )  NUL terminates a string, but isn’t part of it  important for strlen() – length doesn’t include the NUL  Strings are accessed through pointers/array names  #include at program start

7 String 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 m[10] = ″ dog ″ ;

8 String 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 m[10] = ″ dog ″ ; 10 bytes are allocated for this array

9 String 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 m[10] = ″ dog ″ ; 10 bytes are allocated for this array This is not a string literal; It’s an array initializer in disguise! Equivalent to { ′ d ′, ′ o ′, ′ g ′, ′ \0 ′ }

10 String 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);  Programmer’s responsibility to ensure that:  destination region large enough to hold result  source, destination regions don’t overlap  “undefined” behavior in this case – according to C spec, anything could happen! char m[10] = ″ dog ″ ; strcpy(m+1, m);

11 String 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);  Programmer’s responsibility to ensure that:  destination region large enough to hold result  source, destination regions don’t overlap  “undefined” behavior in this case – according to C spec, anything could happen! char m[10] = ″ dog ″ ; strcpy(m+1, 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?

12 strlen() 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) >= 0)...  avoid by casting: ((int) (strlen(x) – strlen(y)) >= 0)  Problem: what if x or y is a very large string?  a better alternative: (strlen(x) >= strlen(y))

13 strlen() 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) >= 0)...  avoid by casting: ((int) (strlen(x)) – strlen(y) >= 0)  Problem: what if x or y is a very large string?  a better alternative: (strlen(x) >= strlen(y)) always true!

14 strcmp() “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!

15 Restricted 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 isn’t large enough, terminating NUL won’t be written Safe alternative: strncpy(buffer, name, BSIZE); buffer[BSIZE-1] = ′ \0 ′ ;

16 String 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 */

17 Functions

18 Functions – basic example #include 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 (a+b); /* return by value */ }

19 Argument Passing

20 What’s wrong with this ? #include 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 temp=32+12; ptr = &(temp); } /* compiles correctly, but gives run-time error */

21 Passing and returning arrays #include void init_array(int array[], int size) ; void main(void) { int list[5]; init_array(list, 5); for (i = 0; i < 5; i++) printf(“next:%d”, array[i]); } void init_array(int array[], int size) { /* why size ? */ /* arrays ALWAYS passed by reference */ int i; for (i = 0; i < size; i++) array[i] = 0; }

22 Structures

23 #include struct birthday{ int month; int day; int year; }; main() { struct birthday mybday;/* - no ‘new’ needed ! */ /* then, it’s just like Java ! */ mybday.day=1; mybday.month=1; mybday.year=1977; printf(“I was born on %d/%d/%d”, birth.day, birth.month, birth.year); } Structures  Equivalent of Java’s classes with only data (no methods)

24 More on Structures struct person{ char name[41]; int age; float height; struct { /* embedded structure */ int month; int day; int year; } birth; }; struct person me; me.birth.year=1977;……… struct person class[60]; /* array of info about everyone in class */ class[0].name=“Gun”; class[0].birth.year=1971;……

25 Passing/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->year); /* warning ! ‘->’, not ‘.’, after a struct pointer*/ }.. /* return struct by value */ struct birthday get_bday(void){ struct birthday newbday; newbday.year=1971; /* ‘.’ after a struct */ return newbday; }/* - also inefficient: why ? */

26 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;*/ Synonym for a data type  Easier to remember  Clean code

27 int month[12]; /* month is a pointer to base address 430*/ month[3] = 7; /* month address + 3 * int elements => int at address (430+3*4) is now 7 */ ptr = month + 2; /* ptr points to month[2], => ptr is now (430+2 * int elements)= 438 */ ptr[5] = 12; /* ptr address + 5 int elements => int at address (434+5*4) is now 12. Thus, month[7] is now 12 */ ptr++; /* ptr <- 438 + 1 * size of int = 442 */ (ptr + 4)[2] = 12; /* accessing ptr[6] i.e., array[9] */ More pointers  Now, month[6], *(month+6), (month+4)[2], ptr[3], *(ptr+3) are all the same integer variable.

28 Memory Layout  How is memory organized?  Text=code, constant data

29 Memory Layout  How is memory organized?  Text=code, constant data  Data = initialized global and static variables

30 Memory Layout  How is memory organized?  Text=code, constant data  Data = initialized global and static variables  BSS = (Block Started by Symbol)

31 Memory Layout  How is memory organized?  Text=code, constant data  Data = initialized global and static variables  BSS = (Block Started by Symbol)  Heap = dynamic memory

32 Memory Layout  How is memory organized?  Text=code, constant data  Data = initialized global and static variables  BSS = (Block Started by Symbol)  Heap = dynamic memory  Stack = local variables

33 Memory Layout

34 Overview of memory management 34  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() main() f() g()

35 Memory Allocation  How is memory allocated?  Global and static variables = program startup

36 Memory Allocation  How is memory allocated?  Global and static variables = program startup  Local variables = function call

37 Memory Allocation  How is memory allocated?  Global and static variables = program startup  Local variables = function call  Dynamic memory = malloc()

38 Memory Allocation

39  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 doesn’t have to search for free memory space!

40 Allocating new heap memory void *malloc(size_t size);  Allocate a block of size bytes, return a pointer to the block ( NULL if unable to allocate block) Note: void * denotes a generic pointer type

41 Memory deallocation  How is memory deallocated?  Global and static variables = program finish

42 Memory deallocation  How is memory deallocated?  Global and static variables = program finish  Local variables = function return

43 Memory deallocation  How is memory deallocated?  Global and static variables = program finish  Local variables = function return  Dynamic memory = free()

44 Memory 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

45 Memory 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

46 Memory deallocation

47 Deallocating 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 you’re 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!

48 Checking for successful allocation  Call to malloc might fail to allocate memory, if there’s not enough available  Easy to forget this check, annoying to have to do it every time malloc is called...

49 Memory 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

50 Using 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 i=10; foo(&i); printf("i = %d\n", i); /* UMR: Using i, which is now junk value */ }

51 Using memory that you don’t own  Null pointer read/write typedef struct node { struct node* next; int val; } Node; int findLastNodeValue(Node* head) { while (head->next != NULL) { /* Expect NPR */ head = head->next; } return head->val; /* Expect ZPR */ } What if head is NULL ?

52 Using memory that you don’t own  Invalid pointer read/write  Pointer to memory that hasn’t 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); }

53 Using memory that you haven’t allocated  Array bound read/write void genABRandABW() { const char *name = “Safety Critical"; char *str = (char*) malloc(10); strncpy(str, name, 10); str[11] = '\0'; /* Expect ABW */ printf("%s\n", str); /* Expect ABR */ }

54 Faulty heap management  Memory leak int *pi; void foo() { pi = (int*) malloc(8*sizeof(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(4*sizeof(int)); /* Expect MLK: foo leaks it */ foo(); }

55 Faulty 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++; }

56 Faulty 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(fum+1); /* Expect FUM: fum+1 points to middle of a block */ free(fum); free(fum); /* Expect FUM: freeing already freed memory */ }

57 Dynamic Memory

58

59

60

61

62

63

64

65

66

67

68 Before you go….  Always initialize anything before using it (especially pointers)  Don’t use pointers after freeing them  Don’t return a function’s 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 haven’t told you – you should be comfortable enough now to read them up by yourself.

69 Dynamic Memory  Code Execution: … start with dog();  Memory: char *cat(char *x, int i) { static int r = 4; x[3] = '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); }

70 Dynamic Memory  Code Execution:  Memory: char *cat(char *x, int i) { static int r = 4; x[3] = '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); }

71 Dynamic Memory  Code Execution:  Memory: char *cat(char *x, int i) { static int r = 4; x[3] = '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); } *s “my cat”

72 Dynamic Memory  Code Execution:  Memory: char *cat(char *x, int i) { static int r = 4; x[3] = '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); } *s “my cat” z = 12

73 Dynamic Memory  Code Execution:  Memory: char *cat(char *x, int i) { static int r = 4; x[3] = '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); } *s “my cat” z = 12 *x i = 12 cat() Stack Frame dog() Stack Frame

74 Dynamic Memory  Code Execution:  Memory: char *cat(char *x, int i) { static int r = 4; x[3] = '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); } *s “my cat” z = 12 *x i = 12 r = 4 cat() Stack Frame dog() Stack Frame Static Memory

75 Dynamic Memory  Code Execution:  Memory: char *cat(char *x, int i) { static int r = 4; x[3] = '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); } *s “my hat” z = 12 *x i = 12 r = 4 cat() Stack Frame dog() Stack Frame Static Memory

76 Dynamic Memory  Code Execution:  Memory: char *cat(char *x, int i) { static int r = 4; x[3] = '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); } *s “my hat” z = 12 *x i = 12 r = 4 cat() Stack Frame dog() Stack Frame Static Memory *result 20 bytes Heap Memory

77 Dynamic Memory  Code Execution:  Memory: char *cat(char *x, int i) { static int r = 4; x[3] = '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); } *s “my hat” z = 12 *x i = 12 r = 4 cat() Stack Frame dog() Stack Frame Static Memory *result “my hat x 12” Heap Memory

78 Dynamic Memory  Code Execution:  Memory: char *cat(char *x, int i) { static int r = 4; x[3] = '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); } *s “my hat” z = 12 r = 4 dog() Stack Frame Static Memory “my hat x 12” Heap Memory


Download ppt "Topics This Section  More C basics  Strings  Functions  Structures  Memory."

Similar presentations


Ads by Google