CS 241 Data Organization malloc and free March 20, 2018
<stdlib.h>: malloc() void *malloc(size_t byteSize) • The malloc function allocates unused space for an object whose size in bytes is specified by byteSize . • The order and contiguity of storage allocated by successive calls to malloc is unspecified. • The return value is a void pointer (not void ) A void pointer is aligned so that it may be assigned to a pointer of any object type. For example, on some machines int x can only start on addresses where &x % 4 == 0 . • The pointer returned points to the start (lowest byte address) of the allocated space. • If the requested space cannot be allocated, a NULL pointer is returned.
<stdlib.h>: calloc() void *calloc(size_t numObj, size_t objSize) • Allocates a continuous block of memory large enough to hold numObj items each of objSize bytes. • Also initializes all elements to zero. • Compare with malloc int n = 50; int *a = malloc(n * sizeof(int )); int *b = calloc(n, sizeof(int ));
<stdlib.h>: free() void free (void *ptr); • The free function deallocates a block of memory previously allocated using a call to malloc , (or calloc or realloc ). • After being deallocated, the memory is available for further allocations. • Always call free when done with every pointer returned by malloc . • Never use a pointer after it has been freed. • Never call free with any value other than one returned by malloc .
Dynamic Array Allocation: main() int *num only #include <stdio.h> #include <stdlib.h> allocates memory for #include <limits.h> a pointer to an int. #define END_CODE INT_MIN int main(void) { int *num = atoiArray("42 427 3 1234 88"); int i=0; while (num[i] != END_CODE) { printf("num[%d]=%d\n", i, num[i]); i++; atoiArray must } allocate memory for free(num); return 0; the actual array. }
Dynamic Array Allocation: atoiArray int* atoiArray(char *line) Given: line ← "42 427 3 1234 88" 1. Find n , the number of numbers are in line . 2. Allocate memory for an array of int of size n+1 (add one for the terminating symbol). 3. Convert the characters in the string to numbers in the array. 4. Add the terminating symbol. 5. Return a pointer to the allocated int array.
Dynamic Array Allocation: atoiArray int* atoiArray(char *line) { /* Find out how many numbers in line */ int n=1; char* charPt = line; while (* charPt) { if (* charPt == ’ ’) n++; charPt ++; } printf("%d numbers in string .\n", n); /* Allocate memory of for array of int */ int *num = malloc(sizeof(int )*(n+1));
Dynamic Array Allocation: atoiArray /* Convert string to numbers in the array */ int* intPt = num; *intPt = 0; charPt = line; /* reset to line start */ int startedNewNumber = 0; while (* charPt) { if (* charPt == ’ ’) { printf("Done with: %d\n", *intPt ); intPt ++; *intPt = 0; startedNewNumber = 0; } else { *intPt = *intPt *10 + (*charPt -’0’); startedNewNumber = 1; } charPt ++; }
Dynamic Array Allocation: atoiArray /* Add terminating symbol */ if ( startedNewNumber ) intPt ++; *intPt = END_CODE; /* Return a pointer the allocated int array */ return num; }
valgrind Valgrind is an open source programming tool for detection of memory leaks, invalid memory usage, and profiling. The name valgrind comes from the main entrance to Valhalla in Norse mythology. valgrind a.out Runs a.out in a virtual machine. Example: If a.out is the Binary Tree code in the textbook: ... ==24825== LEAK SUMMARY: ==24825== definitely lost: 32 bytes in 1 blocks ==24825== indirectly lost: 88 bytes in 5 blocks ...
Dynamically Sized, 2D Array with malloc #include <stdio.h> #include <stdlib.h> void print2DArray(int **array , int rows , int cols) { /* Body on separate slide */ } void set2DArray(int **array , int rows , int cols) { /* Body on separate slide */ } void main(void) { /* Body on separate slide */ }
Dynamically Sized, 2D Array: main void main(void) { int columns = 3; int rows = 4; int ** array; array = malloc(columns * sizeof (* array )); int col; for (col = 0; col <columns; col ++) { array[col] = malloc(rows*sizeof(int )); } setArray(array , columns , rows ); printArray(array , columns , rows ); }
Dynamically Sized, 2D Array: setArray void setArray(int **array , int cols , int rows) { int r, c; int data = 0; for (c=0; c<cols; c++) { for (r=0; r<rows; r++) { array[c][r] = data; data ++; } } } Incrementing data so each cell gets a different value in this example.
Dynamically Sized, 2D Array: printArray void printArray(int **array , int cols , int rows) { r=0 [ 0 4 8 ] int r, c; for (r=0; r<rows; r++) r=1 [ 1 5 9 ] { r=2 [ 2 6 10 ] printf("r=%d [", r); r=3 [ 3 7 11 ] for (c=0; c<cols; c++) { printf("%3d ", array[c][r]); } printf("]\n"); } }
Uh-oh, forgot to clean up. . . Where should I add the call(s) to free ?
Recommend
More recommend