Download presentation
Presentation is loading. Please wait.
1
. Plab – Tirgul 4 structs & arrays, file I/O, debugging memory errors
2
Assignment: struct vs. pointer to struct x=7 Complex c1, c2; c1.x=7; c1.y=3; c2 = c1; y=3 x=7 y=3 c1c2 Complex *cp1, *cp2; cp1 = (Complex*)malloc... cp2 = (Complex*)malloc... cp1->x=7; cp1->y=3; cp2 = cp1; x=7 y=3 garbage cp1cp2 struct Complex { double x,y; };
3
u When an array is passed as an argument to a function, the address of the 1 st element is passed. u Structs are passed by value, exactly as the basic types. Arrays & structs as arguments
4
struct MyStr { int a[10]; }; void f(int a[]) { a[7] = 89; } void g(MyStr s) { s.a[7] = 84; } main() { MyStr x; x.a[7] = 0; f(x.a); printf("%d\n", x.a[7]); g(x); printf("%d\n", x.a[7]); } Output: 89
5
argv & argc To pass command line arguments to our program we should use the following main declaration: main(int argc, char* argv[]) {... Compare to main(String[] args) in java. u Unlike java the first argument is the name of the program itself. char** argv char argv[][]
6
argv & argc: example $ prog1 –u danny –p 1234 argc = 5 argv[0] = “prog1” argv[1] = “-u”... argv[4] = “1234” Always: argv[argc] = 0
7
Default function arguments u We can specify default value for trailing arguments of a function. An alternative to overloading. Example: print(int value, int base=10) {... print(31, 16); print(31);// equivalent to print(31,10) h(int x=0, int y) // error! Only in C++
8
File I/O u File I/O is mostly similar to stdin & stdout I/O. Most I/O functions we encountered have a “file” counterpart which receives a FILE pointer (handle). Examples: getchar(void) fgetc(FILE*) scanf(const char *,...) fscanf(FILE*, const char*,...) printf(const char *,...) fprintf(FILE*, const char*,...) The standard streams ( stdin, stdout, stderr ) are also of FILE* type. See related man pages: fprintf, fscanf, etc.
9
File I/O example: mywc #include #include #include main(int argc, char* argv[]) { FILE* fp; int wc = 0, ch; if (argc != 2) { printf("Usage: mywc \n"); exit(1); } errno = 0; fp = fopen(argv[1], "r"); if (fp == NULL) { perror(“”); exit(1); }
10
File I/O example while (1) { while ((ch = fgetc(fp)) != EOF && isspace(ch)) ; if (ch == EOF) break; wc++; while ((ch = fgetc(fp)) != EOF && !isspace(ch)) ; if (ch == EOF) break; } fclose(fp); printf("There are %d words in %s\n", wc, argv[1]); return 0; } Related man pages: fopen, fclose
11
. Memory related bugs Memory leaks. Accessing random/freed memory addresses (e.g. off-by-one errors).
12
malloc_stats() By including malloc.h you can use the malloc_stats() function which prints to the stderr information about the amount of used memory. u Example:... malloc_stats(); destroyDictionary(dict); malloc_stats();...
13
malloc_stats() cntd. With memory leak: Arena 0: system bytes = 8140 in use bytes = 6860... Arena 0: system bytes = 8140 in use bytes = 4084... Without memory leak: Arena 0: system bytes = 8124 in use bytes = 6860... Arena 0: system bytes = 8124 in use bytes = 4...
14
mtrace u Log all memory allocations to a file. The file name is contained in the MALLOC_TRACE environment variable. For example: $setenv MALLOC_TRACE ~/plab/ex1/trace Analyze the file to find memory leaks using the mtrace utility. u The program must: be compiled with –g flag #include
15
mtrace example The program: #include int main() { mtrace(); // later we can call muntrace()... The trace file looks like this: = Start @ [0x80486fd] + 0x804a0e0 0x8 @ [0x804887d] + 0x804a0f0 0x8 @ [0x8048c7d] + 0x804a100 0x14 @ /lib/libc.so.6:(__strdup+0x29)[0x400d7a29] + 0x804a118 0x5 @ [0x8048c7d] + 0x804a128 0x14 @ /lib/libc.so.6:(__strdup+0x29)[0x400d7a29] + 0x804a140 0x3 @ [0x8048c7d] + 0x804a150 0x14...
16
mtrace example cntd. The result of analysis ( $ mtrace ex1 trace ) Memory not freed: ----------------- Address Size Caller 0x0804a100 0x14 at /home/mush/plab/ex1/strBinTree.c:65 0x0804a128 0x14 at /home/mush/plab/ex1/strBinTree.c:65 0x0804a150 0x14 at /home/mush/plab/ex1/strBinTree.c:65 Memory not freed: ----------------- Address Size Caller 0x0804a118 0x5 at /lib/libc.so.6:(__strdup+0x29)[0x400d7a29] 0x0804a140 0x3 at /lib/libc.so.6:(__strdup+0x29)[0x400d7a29] Another example:
17
MALLOC_CHECK_ By setting this environment variable to 0, 1, 2 we can handle some bugs, most notably freeing twice the same memory. u Usually double free causes segmentation fault. When MALLOC_CHECK_ is 0 freeing twice works. When MALLOC_CHECK_ is 1 an error message is printed. Example: free(): invalid pointer 0x80497b8! When MALLOC_CHECK_ is 2 the program (gracefully) aborts.
18
ElectricFence u ElectricFence is a library which allows to catch accesses to memory that was already freed, as well as off-by-one errors. u It will cause the program to segfault in the above cases, which is usually better than continue running and have unpredictable errors later. Example: char* a = (char*)malloc(100*sizeof(char));... a[100] = 'c'; // ElectricFence will cause segfault
19
ElectricFence cntd. Example: Node* n1 = (Node*)malloc(sizeof(Node));... free(n1);... n1->x = 7; // ElectricFence will cause segfault To use ElectricFence you should link your program with the efence library. For example: g++ prog1.o list.o read.o -lefence
20
Commercial products u Purify u BoundsChecker u MS’s VisualStudio
Similar presentations
© 2024 SlidePlayer.com. Inc.
All rights reserved.