/* MALLOC DEMO #4 Illustrates: declaring a dynamic array of pointers malloc'ing that pointer in a function use of malloc function on that array use of the free function on that array passing pointers into functions the ** prototype (pointer to a pointer) the *** prototype (pointer to a pointer to a pointer) */ #include /* string libraries etc */ #include /* input output */ #include #define MAX_WORDLEN 50 /* F U N C T I O N P R O T O T Y P E S */ void mallocArray( char ***array, int wordCapacity); /* ptr to ptr to ptr (pointer to array of strings) */ void loadArray( char * inFile, char ***arr, int * wordCount, int * wordCapacity ); void printArray( char **arr, int wordCount ); void freeArray( char **word, int wordCount ); void fatal( char * errmsg); /* M A I N F U N C T I O N */ int main( int argc, char *argv[] ) { char **wordArray; /* ptr to ptr (array of strings) */ int wordCount,wordCapacity; if (argc < 2 ) fatal("Must enter a text input filename on cmd line.\n"); /* Note that with out dynamically sized array of ponters we need to additional variables to track the dimension (maxWords) of the array and the current count of elements in use We will dimension the array dynamically from the load AFTER we read a dimension value from the top of the input file. That dimension is assumed to be the number of words in the file */ loadArray( argv[1], &wordArray, &wordCount, &wordCapacity); printf("Printing wordArray:\n\n"); printArray( wordArray, wordCount ); /* again - need only pass array's name */ freeArray( wordArray, wordCount ); /* same here */ wordArray = NULL; return EXIT_SUCCESS; } /* ---------------------------------------------------------------------------*/ /* Takes 2 arg: ptr to a char** ptr and the number of elements to be allocated to that char **pointer */ void mallocArray( char ***array, int wordCapacity ) { *array = malloc( wordCapacity * sizeof( char *) ); if (!*array) fatal("malloc of array failed"); } void loadArray( char * infileName, char ***arr, int * wordCount, int * wordCapacity) { char buffer[MAX_WORDLEN]; FILE * infile; infile = fopen( infileName, "r" ); if (!infile) printf("Can't open specified input file: Exiting Program."); if (fscanf( infile, "%d", wordCapacity ) != 1) /* fscanf of numbers is OK - (fscanf on strings is dangerous) */ fatal("Can't read expected count value from top of infile"); mallocArray( arr, *wordCapacity ); *wordCount=0; /* DANGER: fscanf of string vulnerable to overflow. We use fgets (for now) */ while ( (*wordCount < *wordCapacity) && fgets(buffer, MAX_WORDLEN, infile) ) /* WARNING: fgets vulnerable to truncation but not overflow */ { (*arr)[*wordCount] = malloc( (strlen(buffer)+1) * sizeof(char) ); if ((*arr)[*wordCount]==NULL) /* ALWAYS CHECK FOR NULL */ { fatal("malloc failed: Exiting Program."); exit( EXIT_FAILURE ); /* a NON_ZERO value */ } strcpy( (*arr)[*wordCount], buffer ); ++(*wordCount); } fclose(infile); } /* --------------------------------------------------------------------------- Takes 2 args: the name of an array of pointers, and a count of how many pointers have been malloc'd. Prints each string. */ void printArray( char **arr, int wordCount ) { int i; for(i=0 ; i