Presentation is loading. Please wait.

Presentation is loading. Please wait.

1 C Basics Monday, August 30, 2010 CS 241. Announcements MP1, a short machine problem, will be released today. Due: Tuesday, Sept. 7 th at 11:59pm via.

Similar presentations


Presentation on theme: "1 C Basics Monday, August 30, 2010 CS 241. Announcements MP1, a short machine problem, will be released today. Due: Tuesday, Sept. 7 th at 11:59pm via."— Presentation transcript:

1 1 C Basics Monday, August 30, 2010 CS 241

2 Announcements MP1, a short machine problem, will be released today. Due: Tuesday, Sept. 7 th at 11:59pm via svn Due Tuesday due to the holiday, but MP2 will be due on Monday. Make sure to read the MP1 README and CS241.html on the course website before beginning the MP! 2

3 Understanding C / C++ C++’s initial development Problem: Object oriented languages provided nice features to programmers, but were very, very slow The development of C++ was an answer to provide objects to C. C++ was originally called “C with Classes” (1979) Result: C++ was developed from C 3

4 Understanding C / C++ Result: C++ was developed from C Everything you can do in C++ (or Java, or C#, or Perl, or Python) can be done in C! All of the syntax you use in this class is valid C++. All of C++ syntax you’ve used, however, is not valid C. 4

5 Key Differences C does not have “ iostreams ” Must use printf() rather than cout printf("hello world\n“); v. cout<<"hello world“<<endl; Must use malloc()/free() rather than new/delete to allocate heap memory int *x = malloc(8 * sizeof(int)); free(x); int *x = new int[8]; delete(x); 5

6 Common MP Mistakes First Mistake: Assuming memory has been set to 0 for you. 6

7 C-Strings In C, there is not a data type “ string ”. Strings in C, sometimes called “C-strings”, are arrays of characters C-strings are terminated by a NULL character (ASCII: 0, Text: '\0' ) 7

8 C-Strings Consider the code: char *s = “Hello World!” In memory: 8 HelloWorld!\0 s

9 C-Strings In Java, you can concatenate strings by: string s = s + " World!"; In C, C-Strings are only pointers, so you can’t do: char *s = s + " World!"; …you would get the sum of two memory locations! 9

10 C-Strings In Java, you can concatenate strings by: string s = s + " World!"; Instead, you have to use strcat(): strcat(s, " World!"); 10

11 strcat() strcat(char *destination, char *source) works by: Find the end of the destination string Append the source string to the end of the destination string Add a NULL to new destination string 11

12 C-Strings Consider the following code: char *s = malloc(11 * sizeof(char)); /* Allocate enough memory for an array of 11 characters, enough to store a 10-char long string. */ strcat(s, "Hello"); strcat(s, "World"); 12

13 C-Strings Consider the following code: char *s = malloc(11 * sizeof(char)); /* Allocate enough memory for an array of 11 characters, enough to store a 10-char long string. */ strcat(s, "Hello"); strcat(s, "World"); 13 ?? s

14 C-Strings Consider the following code: char *s = malloc(11 * sizeof(char)); /* Allocate enough memory for an array of 11 characters, enough to store a 10-char long string. */ strcat(s, "Hello"); strcat(s, "World"); 14 ?? s

15 C-Strings Consider the following code: char *s = malloc(11 * sizeof(char)); /* Allocate enough memory for an array of 11 characters, enough to store a 10-char long string. */ strcat(s, "Hello"); strcat(s, "World"); 15 ?? s Yikes! We don’t know where the C-string s actually ends! Since the OS doesn’t “clear” the memory for us, we’ll keep walking the memory until we find a ‘\0’. This could mean we write in memory we didn’t allocate (buffer overflow) or write in memory we can’t write in (segmentation fault)!

16 C-Strings Correctly Problem: We never initialized our C- string to be empty! Fix: Initialize the first character to be empty! 16

17 C-Strings (Correctly) Consider the following code: char *s = malloc(11 * sizeof(char)); /* Allocate enough memory for an array of 11 characters, enough to store a 10-char long string. */ s[0] = '\0'; strcat(s, "Hello"); strcat(s, "World"); 17

18 C-Strings (Correctly) Consider the following code: char *s = malloc(11 * sizeof(char)); /* Allocate enough memory for an array of 11 characters, enough to store a 10-char long string. */ s[0] = '\0'; strcat(s, "Hello"); strcat(s, "World"); 18 ?? s

19 C-Strings (Correctly) Consider the following code: char *s = malloc(11 * sizeof(char)); /* Allocate enough memory for an array of 11 characters, enough to store a 10-char long string. */ s[0] = '\0'; strcat(s, "Hello"); strcat(s, "World"); 19 \0 s ??

20 C-Strings (Correctly) Consider the following code: char *s = malloc(11 * sizeof(char)); /* Allocate enough memory for an array of 11 characters, enough to store a 10-char long string. */ s[0] = '\0'; strcat(s, "Hello"); strcat(s, "World"); 20 H s ello\0??

21 C-Strings (Correctly) Consider the following code: char *s = malloc(11 * sizeof(char)); /* Allocate enough memory for an array of 11 characters, enough to store a 10-char long string. */ s[0] = '\0'; strcat(s, "Hello"); strcat(s, "World"); 21 H s elloWorld\0

22 Common MP Mistakes First Mistake: Assuming memory has been set to 0 for you. Common Related Mistake: You must always allocate to the length of the string plus one! strlen("Hello"); …returns 5. …takes 6 (six) bytes to store in memory. 22

23 Common MP Mistakes First Mistake: Assuming memory has been set to 0 for you. Second Mistake: Returning a variable in stack memory from a function. 23

24 Common MP Mistakes Second Mistake: Returning a variable in stack memory from a function. What is stack memory? 24

25 Lets look at some code… int b() { /* … */ } int a() { /* … */ b(); } int main(int argc, char **argv) { /* … */ a(); } 25 At the beginning of the program, the OS will create a stack frame for the main() function. main() Stack Memory:

26 Lets look at some code… int b() { /* … */ } int a() { /* … */ b(); } int main(int argc, char **argv) { /* … */ a(); } 26 The main() function will eventually call the function a(). Stack Memory: main()

27 Lets look at some code… int b() { /* … */ } int a() { /* … */ b(); } int main(int argc, char **argv) { /* … */ a(); } 27 When a() is called, the OS will create a new stack frame for a(). Stack Memory: main() a()

28 Lets look at some code… int b() { /* … */ } int a() { /* … */ b(); } int main(int argc, char **argv) { /* … */ a(); } 28 When b() is called, the same is done… Stack Memory: main() a()

29 Lets look at some code… int b() { /* … */ } int a() { /* … */ b(); } int main(int argc, char **argv) { /* … */ a(); } 29 b()’s stack frame is now in memory… Stack Memory: main() a() b()

30 Lets look at some code… int b() { /* … */ } int a() { /* … */ b(); } int main(int argc, char **argv) { /* … */ a(); } 30 When b() finishes running, its stack frame is removed! Stack Memory: main() a() b()

31 Lets look at some code… int b() { /* … */ } int a() { /* … */ b(); } int main(int argc, char **argv) { /* … */ a(); } 31 When b() finishes running, its stack frame is removed! Stack Memory: main() a() b()

32 Lets look at some code… int b() { /* … */ } int a() { /* … */ b(); } int main(int argc, char **argv) { /* … */ a(); } 32 …but why clear the memory? We just mark it as ‘free’. Stack Memory: main() a() b()

33 Lets look at some code… int b() { /* … */ } int a() { /* … */ b(); } int main(int argc, char **argv) { /* … */ a(); } 33 And the process would continue… Stack Memory: main() a() b()

34 Lets look at some code… int b() { /* … */ } int a() { /* … */ b(); } int main(int argc, char **argv) { /* … */ a(); } 34 Stack Memory: main() a() b()

35 Lets look at some code… int b() { /* … */ } int a() { /* … */ b(); } int main(int argc, char **argv) { /* … */ a(); } 35 Stack Memory: main() a() b()

36 What’s in the stack frame? The concept of a stack frame is important, since the stack frame contains all of the function’s stack variables! Lets make our code slightly more interesting… 36

37 Lets look at some code… my_queue * b() { my_queue q; return &q; } int a(int yourVal) { int myVal; my_queue *myQueue; myVal = yourVal + 3; myQueue = b(); return remove_int(myQueue); } 37 int main(int argc, char **argv) { int myVal = 3; a(myVal); } Looking at the code: - main() still calls a() - a() still calls b() - b() should return a pointer to a() - a() should return an int to main() - my_queue is just some custom struct

38 Lets look at some code… my_queue * b() { my_queue q; return &q; } int a(int yourVal) { int myVal; my_queue *myQueue; myVal = yourVal + 3; myQueue = b(); return remove_int(myQueue); } 38 int main(int argc, char **argv) { int myVal = 3; a(myVal); } argc (4 bytes) **argv (8 bytes) 1 0x…

39 Lets look at some code… my_queue * b() { my_queue q; return &q; } int a(int yourVal) { int myVal; my_queue *myQueue; myVal = yourVal + 3; myQueue = b(); return remove_int(myQueue); } 39 int main(int argc, char **argv) { int myVal = 3; a(myVal); } argc (4 bytes) **argv (8 bytes) myVal (4 bytes) 1 0x… 3

40 Lets look at some code… my_queue * b() { my_queue q; return &q; } int a(int yourVal) { int myVal; my_queue *myQueue; myVal = yourVal + 3; myQueue = b(); return remove_int(myQueue); } 40 int main(int argc, char **argv) { int myVal = 3; a(myVal); } argc (4 bytes) **argv (8 bytes) myVal (4 bytes) 1 0x… 3 yourVal (4 bytes) 3

41 Lets look at some code… my_queue * b() { my_queue q; return &q; } int a(int yourVal) { int myVal; my_queue *myQueue; myVal = yourVal + 3; myQueue = b(); return remove_int(myQueue); } 41 int main(int argc, char **argv) { int myVal = 3; a(myVal); } argc (4 bytes) **argv (8 bytes) myVal (4 bytes) 1 0x… 3 yourVal (4 bytes) 3 myVal (4 bytes) ???????

42 Lets look at some code… my_queue * b() { my_queue q; return &q; } int a(int yourVal) { int myVal; my_queue *myQueue; myVal = yourVal + 3; myQueue = b(); return remove_int(myQueue); } 42 int main(int argc, char **argv) { int myVal = 3; a(myVal); } argc (4 bytes) **argv (8 bytes) myVal (4 bytes) 1 0x… 3 yourVal (4 bytes) 3 myVal (4 bytes) ??????? *myQueue (8 bytes) ???????

43 Lets look at some code… my_queue * b() { my_queue q; return &q; } int a(int yourVal) { int myVal; my_queue *myQueue; myVal = yourVal + 3; myQueue = b(); return remove_int(myQueue); } 43 int main(int argc, char **argv) { int myVal = 3; a(myVal); } argc (4 bytes) **argv (8 bytes) myVal (4 bytes) 1 0x… 3 yourVal (4 bytes) 3 myVal (4 bytes) 6 *myQueue (8 bytes) ???????

44 Lets look at some code… my_queue * b() { my_queue q; return &q; } int a(int yourVal) { int myVal; my_queue *myQueue; myVal = yourVal + 3; myQueue = b(); return remove_int(myQueue); } 44 int main(int argc, char **argv) { int myVal = 3; a(myVal); } argc (4 bytes) **argv (8 bytes) myVal (4 bytes) 1 0x… 3 yourVal (4 bytes) 3 myVal (4 bytes) 6 *myQueue (8 bytes) ???????

45 Lets look at some code… my_queue * b() { my_queue q; return &q; } int a(int yourVal) { int myVal; my_queue *myQueue; myVal = yourVal + 3; myQueue = b(); return remove_int(myQueue); } 45 int main(int argc, char **argv) { int myVal = 3; a(myVal); } argc (4 bytes) **argv (8 bytes) myVal (4 bytes) 1 0x… 3 yourVal (4 bytes) 3 myVal (4 bytes) 6 *myQueue (8 bytes) ??????? q (? bytes) (struct data)

46 Lets look at some code… my_queue * b() { my_queue q; return &q; } int a(int yourVal) { int myVal; my_queue *myQueue; myVal = yourVal + 3; myQueue = b(); return remove_int(myQueue); } 46 int main(int argc, char **argv) { int myVal = 3; a(myVal); } argc (4 bytes) **argv (8 bytes) myVal (4 bytes) 1 0x… 3 yourVal (4 bytes) 3 myVal (4 bytes) 6 *myQueue (8 bytes) ??????? q (? bytes) (struct data)

47 Lets look at some code… my_queue * b() { my_queue q; return &q; } int a(int yourVal) { int myVal; my_queue *myQueue; myVal = yourVal + 3; myQueue = b(); return remove_int(myQueue); } 47 int main(int argc, char **argv) { int myVal = 3; a(myVal); } argc (4 bytes) **argv (8 bytes) myVal (4 bytes) 1 0x… 3 yourVal (4 bytes) 3 myVal (4 bytes) 6 *myQueue (8 bytes) ??????? q (? bytes) (struct data)

48 Lets look at some code… my_queue * b() { my_queue q; return &q; } int a(int yourVal) { int myVal; my_queue *myQueue; myVal = yourVal + 3; myQueue = b(); return remove_int(myQueue); } 48 int main(int argc, char **argv) { int myVal = 3; a(myVal); } argc (4 bytes) **argv (8 bytes) myVal (4 bytes) 1 0x… 3 yourVal (4 bytes) 3 myVal (4 bytes) 6 *myQueue (8 bytes) ??????? q (? bytes) (struct data)

49 Lets look at some code… my_queue * b() { my_queue q; return &q; } int a(int yourVal) { int myVal; my_queue *myQueue; myVal = yourVal + 3; myQueue = b(); return remove_int(myQueue); } 49 int main(int argc, char **argv) { int myVal = 3; a(myVal); } argc (4 bytes) **argv (8 bytes) myVal (4 bytes) 1 0x… 3 yourVal (4 bytes) 3 myVal (4 bytes) 6 *myQueue (8 bytes) 0x… q (? bytes) (struct data)

50 Lets look at some code… my_queue * b() { my_queue q; return &q; } int a(int yourVal) { int myVal; my_queue *myQueue; myVal = yourVal + 3; myQueue = b(); return remove_int(myQueue); } 50 int main(int argc, char **argv) { int myVal = 3; a(myVal); } argc (4 bytes) **argv (8 bytes) myVal (4 bytes) 1 0x… 3 yourVal (4 bytes) 3 myVal (4 bytes) 6 *myQueue (8 bytes) 0x… q (? bytes) (struct data)

51 Lets look at some code… my_queue * b() { my_queue q; return &q; } int a(int yourVal) { int myVal; my_queue *myQueue; myVal = yourVal + 3; myQueue = b(); return remove_int(myQueue); } 51 int main(int argc, char **argv) { int myVal = 3; a(myVal); } argc (4 bytes) **argv (8 bytes) myVal (4 bytes) 1 0x… 3 yourVal (4 bytes) 3 myVal (4 bytes) 6 *myQueue (8 bytes) 0x… q (? bytes) (struct data) Yikes! We don’t know if the data that is pointed to by myQueue is valid anymore. Sometimes, the OS may have kept it around. Other times, other data may have been written there… Result: Your program may run differently different times you run it!

52 What went wrong? Problem: We returned a stack variable; unpredictable if the variable is available outside of its stack frame. Fix: Three ‘common’ fixes: Good: Pass in the variable you want to use Good: Use a heap variable Very Bad: Use a global variable 52

53 Fix 1: Pass in the variable my_queue * b(my_queue *q) { /* … */ return q; } 53 int a(…) { int myVal; my_queue *myQueue; myVal = yourVal + 3; myQueue = b(myQueue); return remove_int(myQueue); }

54 Fix 2: Use heap memory my_queue * b() { my_queue *q = malloc( sizeof(my_queue)); /* … */ return q; } 54 int a(…) { int myVal; my_queue *myQueue; myVal = yourVal + 3; myQueue = b(myQueue); in returnVal = remove_int(myQueue); free(myQueue); return returnVal; } Note: If you malloc() memory, you must free() it!

55 …but we have valgrind! One tool available on most linux boxes (including the csil-linux-ts machines): valgrind valgrind will report memory leaks and invalid memory accesses to you 15% of your MP grade on each MP is based on if you’ve freed all your memory! 55

56 Using valgrind… Remember our string program: char *s = malloc(11 * sizeof(char)); strcat(s, "Hello"); strcat(s, "World"); I’ve programmed that up into “mystring.c”… 56

57 mystring.c #include int main() { char *s = malloc(11 * sizeof(char)); strcat(s, "Hello"); strcat(s, "World"); return 0; } 57

58 Using valgrind… wfagen2|csil-linux-ts2|~/temp|[9]% gcc mystring.c -o mystring wfagen2|csil-linux-ts2|~/temp|[10]% valgrind mystring ==24360== Memcheck, a memory error detector. ==24360== Copyright (C) 2002-2006, and GNU GPL'd, by Julian Seward et al. ==24360== Using LibVEX rev 1658, a library for dynamic binary translation. ==24360== Copyright (C) 2004-2006, and GNU GPL'd, by OpenWorks LLP. ==24360== Using valgrind-3.2.1, a dynamic binary instrumentation framework. ==24360== Copyright (C) 2000-2006, and GNU GPL'd, by Julian Seward et al. ==24360== For more details, rerun with: -v ==24360== ==24360== Conditional jump or move depends on uninitialised value(s) ==24360== at 0x4004C7: main (in /home/cs/wfagen2/temp/mystring) ==24360== ==24360== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 4 from 1) ==24360== malloc/free: in use at exit: 11 bytes in 1 blocks. ==24360== malloc/free: 1 allocs, 0 frees, 11 bytes allocated. ==24360== For counts of detected errors, rerun with: -v ==24360== searching for pointers to 1 not-freed blocks. ==24360== checked 64,568 bytes. ==24360== ==24360== LEAK SUMMARY: ==24360== definitely lost: 11 bytes in 1 blocks. ==24360== possibly lost: 0 bytes in 0 blocks. ==24360== still reachable: 0 bytes in 0 blocks. ==24360== suppressed: 0 bytes in 0 blocks. ==24360== Use --leak-check=full to see details of leaked memory. 58

59 Using valgrind… wfagen2|csil-linux-ts2|~/temp|[9]% gcc mystring.c -o mystring wfagen2|csil-linux-ts2|~/temp|[10]% valgrind mystring ==24360== Memcheck, a memory error detector. ==24360== Copyright (C) 2002-2006, and GNU GPL'd, by Julian Seward et al. ==24360== Using LibVEX rev 1658, a library for dynamic binary translation. ==24360== Copyright (C) 2004-2006, and GNU GPL'd, by OpenWorks LLP. ==24360== Using valgrind-3.2.1, a dynamic binary instrumentation framework. ==24360== Copyright (C) 2000-2006, and GNU GPL'd, by Julian Seward et al. ==24360== For more details, rerun with: -v ==24360== ==24360== Conditional jump or move depends on uninitialised value(s) ==24360== at 0x4004C7: main (in /home/cs/wfagen2/temp/mystring) ==24360== ==24360== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 4 from 1) ==24360== malloc/free: in use at exit: 11 bytes in 1 blocks. ==24360== malloc/free: 1 allocs, 0 frees, 11 bytes allocated. ==24360== For counts of detected errors, rerun with: -v ==24360== searching for pointers to 1 not-freed blocks. ==24360== checked 64,568 bytes. ==24360== ==24360== LEAK SUMMARY: ==24360== definitely lost: 11 bytes in 1 blocks. ==24360== possibly lost: 0 bytes in 0 blocks. ==24360== still reachable: 0 bytes in 0 blocks. ==24360== suppressed: 0 bytes in 0 blocks. ==24360== Use --leak-check=full to see details of leaked memory. 59 Problem #1 Conditional jump or move depends on uninitialised value(s) at 0x4004C7: main (in /home/cs/wfagen2/temp/mystring)

60 Using valgrind… wfagen2|csil-linux-ts2|~/temp|[9]% gcc mystring.c -o mystring wfagen2|csil-linux-ts2|~/temp|[10]% valgrind mystring ==24360== Memcheck, a memory error detector. ==24360== Copyright (C) 2002-2006, and GNU GPL'd, by Julian Seward et al. ==24360== Using LibVEX rev 1658, a library for dynamic binary translation. ==24360== Copyright (C) 2004-2006, and GNU GPL'd, by OpenWorks LLP. ==24360== Using valgrind-3.2.1, a dynamic binary instrumentation framework. ==24360== Copyright (C) 2000-2006, and GNU GPL'd, by Julian Seward et al. ==24360== For more details, rerun with: -v ==24360== ==24360== Conditional jump or move depends on uninitialised value(s) ==24360== at 0x4004C7: main (in /home/cs/wfagen2/temp/mystring) ==24360== ==24360== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 4 from 1) ==24360== malloc/free: in use at exit: 11 bytes in 1 blocks. ==24360== malloc/free: 1 allocs, 0 frees, 11 bytes allocated. ==24360== For counts of detected errors, rerun with: -v ==24360== searching for pointers to 1 not-freed blocks. ==24360== checked 64,568 bytes. ==24360== ==24360== LEAK SUMMARY: ==24360== definitely lost: 11 bytes in 1 blocks. ==24360== possibly lost: 0 bytes in 0 blocks. ==24360== still reachable: 0 bytes in 0 blocks. ==24360== suppressed: 0 bytes in 0 blocks. ==24360== Use --leak-check=full to see details of leaked memory. 60 Problem #1 Conditional jump or move depends on uninitialised value(s) at 0x4004C7: main (in /home/cs/wfagen2/temp/mystring) Fix: Initialize your string to be empty.

61 Using valgrind… wfagen2|csil-linux-ts2|~/temp|[9]% gcc mystring.c -o mystring wfagen2|csil-linux-ts2|~/temp|[10]% valgrind mystring ==24360== Memcheck, a memory error detector. ==24360== Copyright (C) 2002-2006, and GNU GPL'd, by Julian Seward et al. ==24360== Using LibVEX rev 1658, a library for dynamic binary translation. ==24360== Copyright (C) 2004-2006, and GNU GPL'd, by OpenWorks LLP. ==24360== Using valgrind-3.2.1, a dynamic binary instrumentation framework. ==24360== Copyright (C) 2000-2006, and GNU GPL'd, by Julian Seward et al. ==24360== For more details, rerun with: -v ==24360== ==24360== Conditional jump or move depends on uninitialised value(s) ==24360== at 0x4004C7: main (in /home/cs/wfagen2/temp/mystring) ==24360== ==24360== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 4 from 1) ==24360== malloc/free: in use at exit: 11 bytes in 1 blocks. ==24360== malloc/free: 1 allocs, 0 frees, 11 bytes allocated. ==24360== For counts of detected errors, rerun with: -v ==24360== searching for pointers to 1 not-freed blocks. ==24360== checked 64,568 bytes. ==24360== ==24360== LEAK SUMMARY: ==24360== definitely lost: 11 bytes in 1 blocks. ==24360== possibly lost: 0 bytes in 0 blocks. ==24360== still reachable: 0 bytes in 0 blocks. ==24360== suppressed: 0 bytes in 0 blocks. ==24360== Use --leak-check=full to see details of leaked memory. 61 Problem #2 ==24360== LEAK SUMMARY: ==24360== definitely lost: 11 bytes in 1 blocks.

62 Using valgrind… wfagen2|csil-linux-ts2|~/temp|[9]% gcc mystring.c -o mystring wfagen2|csil-linux-ts2|~/temp|[10]% valgrind mystring ==24360== Memcheck, a memory error detector. ==24360== Copyright (C) 2002-2006, and GNU GPL'd, by Julian Seward et al. ==24360== Using LibVEX rev 1658, a library for dynamic binary translation. ==24360== Copyright (C) 2004-2006, and GNU GPL'd, by OpenWorks LLP. ==24360== Using valgrind-3.2.1, a dynamic binary instrumentation framework. ==24360== Copyright (C) 2000-2006, and GNU GPL'd, by Julian Seward et al. ==24360== For more details, rerun with: -v ==24360== ==24360== Conditional jump or move depends on uninitialised value(s) ==24360== at 0x4004C7: main (in /home/cs/wfagen2/temp/mystring) ==24360== ==24360== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 4 from 1) ==24360== malloc/free: in use at exit: 11 bytes in 1 blocks. ==24360== malloc/free: 1 allocs, 0 frees, 11 bytes allocated. ==24360== For counts of detected errors, rerun with: -v ==24360== searching for pointers to 1 not-freed blocks. ==24360== checked 64,568 bytes. ==24360== ==24360== LEAK SUMMARY: ==24360== definitely lost: 11 bytes in 1 blocks. ==24360== possibly lost: 0 bytes in 0 blocks. ==24360== still reachable: 0 bytes in 0 blocks. ==24360== suppressed: 0 bytes in 0 blocks. ==24360== Use --leak-check=full to see details of leaked memory. 62 Problem #2 ==24360== LEAK SUMMARY: ==24360== definitely lost: 11 bytes in 1 blocks. Fix: free() all malloc()’d memory!

63 mystring-2.c #include int main() { char *s = malloc(11 * sizeof(char)); s[0] = '\0'; strcat(s, "Hello"); strcat(s, "World"); free(s); return 0; } 63

64 Using valgrind… wfagen2|csil-linux-ts2|~/temp|[16]% gcc mystring-2.c -o mystring-2 wfagen2|csil-linux-ts2|~/temp|[17]% valgrind mystring-2 ==25042== Memcheck, a memory error detector. ==25042== Copyright (C) 2002-2006, and GNU GPL'd, by Julian Seward et al. ==25042== Using LibVEX rev 1658, a library for dynamic binary translation. ==25042== Copyright (C) 2004-2006, and GNU GPL'd, by OpenWorks LLP. ==25042== Using valgrind-3.2.1, a dynamic binary instrumentation framework. ==25042== Copyright (C) 2000-2006, and GNU GPL'd, by Julian Seward et al. ==25042== For more details, rerun with: -v ==25042== ==25042== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 4 from 1) ==25042== malloc/free: in use at exit: 0 bytes in 0 blocks. ==25042== malloc/free: 1 allocs, 1 frees, 11 bytes allocated. ==25042== For counts of detected errors, rerun with: -v ==25042== All heap blocks were freed -- no leaks are possible. 64 ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 4 from 1)... All heap blocks were freed -- no leaks are possible.

65 Using valgrind… wfagen2|csil-linux-ts2|~/temp|[16]% gcc mystring-2.c -o mystring-2 wfagen2|csil-linux-ts2|~/temp|[17]% valgrind mystring-2 ==25042== Memcheck, a memory error detector. ==25042== Copyright (C) 2002-2006, and GNU GPL'd, by Julian Seward et al. ==25042== Using LibVEX rev 1658, a library for dynamic binary translation. ==25042== Copyright (C) 2004-2006, and GNU GPL'd, by OpenWorks LLP. ==25042== Using valgrind-3.2.1, a dynamic binary instrumentation framework. ==25042== Copyright (C) 2000-2006, and GNU GPL'd, by Julian Seward et al. ==25042== For more details, rerun with: -v ==25042== ==25042== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 4 from 1) ==25042== malloc/free: in use at exit: 0 bytes in 0 blocks. ==25042== malloc/free: 1 allocs, 1 frees, 11 bytes allocated. ==25042== For counts of detected errors, rerun with: -v ==25042== All heap blocks were freed -- no leaks are possible. 65 ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 4 from 1)... All heap blocks were freed -- no leaks are possible. These two lines are what we want!

66 mystring-3.c #include int main() { char *s = malloc(10 * sizeof(char)); s[0] = '\0'; strcat(s, "Hello"); strcat(s, "World"); free(s); return 0; } 66

67 Using valgrind… wfagen2|csil-linux-ts2|~/temp|[22]% gcc mystring.c -o mystring wfagen2|csil-linux-ts2|~/temp|[23]% valgrind mystring ==25194== Memcheck, a memory error detector. ==25194== Copyright (C) 2002-2006, and GNU GPL'd, by Julian Seward et al. ==25194== Using LibVEX rev 1658, a library for dynamic binary translation. ==25194== Copyright (C) 2004-2006, and GNU GPL'd, by OpenWorks LLP. ==25194== Using valgrind-3.2.1, a dynamic binary instrumentation framework. ==25194== Copyright (C) 2000-2006, and GNU GPL'd, by Julian Seward et al. ==25194== For more details, rerun with: -v ==25194== ==25194== Invalid write of size 2 ==25194== at 0x400559: main (in /home/cs/wfagen2/temp/mystring) ==25194== Address 0x4C37039 is 9 bytes inside a block of size 10 alloc'd ==25194== at 0x4A05809: malloc (vg_replace_malloc.c:149) ==25194== by 0x4004E9: main (in /home/cs/wfagen2/temp/mystring) ==25194== ==25194== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 4 from 1) ==25194== malloc/free: in use at exit: 0 bytes in 0 blocks. ==25194== malloc/free: 1 allocs, 1 frees, 10 bytes allocated. ==25194== For counts of detected errors, rerun with: -v ==25194== All heap blocks were freed -- no leaks are possible. 67 Invalid write of size 2 at 0x400559: main (in /home/cs/wfagen2/temp/mystring) Address 0x4C37039 is 9 bytes inside a block of size 10 alloc'd at 0x4A05809: malloc (vg_replace_malloc.c:149) by 0x4004E9: main (in /home/cs/wfagen2/temp/mystring)

68 Using valgrind… wfagen2|csil-linux-ts2|~/temp|[22]% gcc mystring.c -o mystring wfagen2|csil-linux-ts2|~/temp|[23]% valgrind mystring ==25194== Memcheck, a memory error detector. ==25194== Copyright (C) 2002-2006, and GNU GPL'd, by Julian Seward et al. ==25194== Using LibVEX rev 1658, a library for dynamic binary translation. ==25194== Copyright (C) 2004-2006, and GNU GPL'd, by OpenWorks LLP. ==25194== Using valgrind-3.2.1, a dynamic binary instrumentation framework. ==25194== Copyright (C) 2000-2006, and GNU GPL'd, by Julian Seward et al. ==25194== For more details, rerun with: -v ==25194== ==25194== Invalid write of size 2 ==25194== at 0x400559: main (in /home/cs/wfagen2/temp/mystring) ==25194== Address 0x4C37039 is 9 bytes inside a block of size 10 alloc'd ==25194== at 0x4A05809: malloc (vg_replace_malloc.c:149) ==25194== by 0x4004E9: main (in /home/cs/wfagen2/temp/mystring) ==25194== ==25194== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 4 from 1) ==25194== malloc/free: in use at exit: 0 bytes in 0 blocks. ==25194== malloc/free: 1 allocs, 1 frees, 10 bytes allocated. ==25194== For counts of detected errors, rerun with: -v ==25194== All heap blocks were freed -- no leaks are possible. 68 Invalid write of size 2 at 0x400559: main (in /home/cs/wfagen2/temp/mystring) Address 0x4C37039 is 9 bytes inside a block of size 10 alloc'd at 0x4A05809: malloc (vg_replace_malloc.c:149) by 0x4004E9: main (in /home/cs/wfagen2/temp/mystring) Fix: check for buffer-overflows!

69 Remember… MP1 out today! Due next Tuesday @ 11:59pm Normally due Mondays! Sections start this Thursday! Meets in 0220 SC Prof. Caccamo will be back Wednesday 69


Download ppt "1 C Basics Monday, August 30, 2010 CS 241. Announcements MP1, a short machine problem, will be released today. Due: Tuesday, Sept. 7 th at 11:59pm via."

Similar presentations


Ads by Google