Tirgul 4 Agenda A bit about strings cmd
Tirgul 4 - Agenda �A bit about strings �cmd arguments �Dynamic (re)allocation �Memory errors (or common bugs) �Debugger – self study 1
Strings, again 2
How to copy a string? �#include <stdio. h> #include <string. h> #include <stdlib. h> int main() { const char *p 1 = "hi mom"; char *p 2 =(char*)malloc(strlen(p 1)); strcpy(p 2, p 1); printf("%sn", p 2); free(p 2); return 0; 3 }
How to copy a string? �#include <stdio. h> #include <string. h> #include <stdlib. h> int main() { const char *p 1 = "hi mom"; char *p 2 =(char*)malloc(strlen(p 1)); strcpy(p 2, p 1); printf("%sn", p 2); free(p 2); return 0; 4 }
How to copy a string? �#include <stdio. h> #include <string. h> #include <stdlib. h> int main() { const char *p 1 = "hi mom"; char *p 2 =(char*)malloc(strlen(p 1)+1); strcpy(p 2, p 1); printf("%sn", p 2); free(p 2); return 0; 5 }
Example: strdup � Duplicate a string (part of the standard library): � char* strdup( char const *p ) { int n = strlen(p); char* q =(char*)malloc(sizeof(char)*(n+1)); if( q != NULL ) { strcpy( q, p ); } return q; } 6
Command-line arguments 7 int main(int argc, char* argv[]) { printf(“%s %d %s n”, “you entered”, argc, “arguments”); printf(“%s: %sn”, “the zeroth arg is the program name”, argv[0]); printf(“%s: %sn”, “the first argument is”, argv[1]); printf(“%s: %sn”, “the second argument is, argv[2]); int i; for (i=0; i<argc; ++i) printf(“arg num %d is %sn”, i, argv[i]); … }
File I/O �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) �scanf(const char *, . . . ) �printf(const char *, . . . ) fgetc(FILE*) fscanf(FILE*, const char*, . . . ) fprintf(FILE*, const char*, . . . ) �The standard streams (stdin, stdout, stderr) are also of FILE* type �See related man pages: fprintf, fscanf, etc. 8
File I/O �Example: slabc_ta 3_mywc. c �Code �Related man pages: fopen, fclose �Binary File I/O �fread, fwrite – read/writes “raw” memory 9
Array reallocation – wrong solution int *arr = (int*)malloc(sizeof(int)*array. Size); //put some values in arr int* new. Arr = (int*)malloc(sizeof(int)*(array. Size+1)); //copy values from arr to new. Arr arr = new. Arr; // BAD: lost address of first allocation! 10
Array reallocation �Allocate array on the heap and assign a pointer to it arr 1 11 2 3
Array reallocation �Use temporary pointer to point to the old array. arr temp 1 12 2 3
Array reallocation �Use temporary pointer to point to the old array. �Reallocate new array. arr 13 temp 1 2 3 ? ? ?
Array reallocation �Use temporary pointer to point to the old array. �Reallocate new array. �Copy values from the old array to the new one. arr 14 temp 1 2 3 ? ?
Array reallocation �Use temporary pointer to point to the old array. �Reallocate new array. �Copy values from the old array to the new one. �Free the old array. arr 15 temp 1 2 3 ? ?
Array reallocation – version 1 void reallocate. Memory(int **arr, unsigned int old. Size, unsigned int new. Size) { //partial example (checking alloc…) int *temp = *arr; *arr = (int*)malloc(sizeof(int)*new. Size); int i = 0; while( i < old. Size) { (*arr)[i] = temp[i]; i++; } free(temp); } int main() { int *arr = (int*)malloc(sizeof(int)*arr. Size); //do some stuff … 16 reallocate. Memory(&arr, arr. Size, new. Size); free(arr)
Array reallocation – version 2 int* reallocate. Memory(int *arr, unsigned int old. Size, unsigned int new. Size) { //Partial example due to space limitations int *temp = arr; arr = (int*)malloc(sizeof(int)*new. Size); int i = 0; while( i < old. Size) { arr[i] = temp[i]; i++; } free(temp); return arr; } int main() { int *arr = (int*)malloc(sizeof(int)*arr. Size); //do some stuff… arr = reallocate. Memor(arr, arr. Size, new. Size); 17 free(arr);
Array reallocation – using realloc int * arr = (int*)malloc(sizeof(int)*old. Size); arr = (int*)realloc(arr, sizeof(int)*new. Size); �realloc tries to reallocate the new memory in place, if fails, tries elsewhere �The old data is preserved �The new cells contents is undefined �If arr=NULL, behaves like malloc 18
Bug 1 (1) typedef struct _Student (2) { (2) int id; (3) char * name; (4) } Student; (5) Student * stud = (Student *) malloc( sizeof(Student) ); (6) stud->id = 123456; (7) stud->name = (char *) malloc(100*sizeof(char)); … (8) free(stud); Memory leak of ‘name’! 19
Bug 2 void my. Func() { int * x = random. Num. Ptr(); int result = *x; // unexpected! *x = 17; // accessing unallocated space! } int * random. Num. Ptr() { int j= srand( time(0) ); return &j; } Never return a address of a stack-variable ! 20
Bug 3 void my. Func(char * input) { char * name; if (input != NULL ) { name = (char*)malloc(MAX_SIZE); strcpy(name, input); } … free(name); } if input is NULL => free on an address that was not allocated using malloc. 21
No bug 3 void my. Func(char * input) { char * name=NULL; if (input != NULL ) { name = (char*)malloc(MAX_SIZE); strcpy(name, input); } … free(name); } always initialize pointers to NULL! 22
Memory bugs �Use valgrind! �Self study �See the tutorial at the course website (under TA lectures). 23
Debugger �To see how the program runs �flow �value of variables �Breakpoints �Break on expressions change �Stack Trace: very helpful for seg faults! 24
GDB – Debugger for GCC �http: //www. gnu. org/s/gdb/ � allows you to see what is going on `inside' another program while it executes �Break points and conditional breakpoint �Examining �Ad hoc changes �Stepping �Inspecting crashes 25
GDB – Debugger for GCC �For debug use –g flag: �gcc –Wall –g hello. c –o hello �Run gdb: �gdb hello �Basic commands: �run, next, step, break, condition, continue, where, backtrace �Many tutorials, for example: �http: //www. cs. cmu. edu/~gilpin/tutorial/ �http: //ace. cs. ohiou. edu/~bhumphre/gdb. html 26
Debugging 101 1. “Define” the bug --- reproduce it 2. Use debugger (and other tools e. g. valgrind) 3. Don’t panic --- think! 4. Divide & Conquer 27
- Slides: 27