CMPS 12M Introduction to Data Structures Lab Lab Assignment 4 solution

$24.99

Original Work ?
Category: You will Instantly receive a download link for .ZIP solution file upon Payment

Description

5/5 - (3 votes)

The purpose of this lab assignment is to get more practice programming in C, including the character functions
in the library ctype.h, and dynamic memory allocation using malloc, calloc, and free.
The Character Library
The C standard library ctype.h contains many functions for classifying and handling character data. For
historical reasons the arguments to these functions are of type int rather than char. In order to avoid a
compiler warning (under gcc –std=c99 –Wall), it is necessary to first cast the char argument as int. For
instance, ctype.h contains the function:
int isalnum(int ch);
which returns non-zero (true) if ch is an alphanumeric character (i.e. a letter or a digit), and 0 (false) if ch is
any other type of character. The following C program reads any number of strings from the command line and
classifies each character as either alphanumeric, or non-alphanumeric.
#include
#include
#include
#include
int main(int argc, char* argv[]){
char ch;
int i, j, count;
if( argc>1 )
{
for(i=1; i:: : Assertion failed.
Abort
You can verify this by running ex3.c on the examples page. As previously mentioned, heap memory is deallocated by the free function.
free(p);
Note that all this instruction does is convert the block of heap memory pointed to by p from allocated to free.
The local variable p still stores the address of this block, and therefore it is still possible to dereference p and
alter the contents of the block. Never do this! As previously mentioned, such an operation could lead to
runtime errors that are intermittent and very difficult to trace. Instead, after calling free, set the pointer safely
to NULL.
free(p);
p = NULL;
Now any attempt to follow the pointer p will result in a segmentation fault, which although it is a runtime
error, will happen consistently and can be traced more easily. Another common error occurs when one
reassigns a pointer without first freeing the memory it points to. Consider the following instructions.
int* p;
p = malloc(sizeof(int));
*p = 6;
p = malloc(sizeof(int));
*p = 7;
Observe that the address of the block of heap memory storing the value 6 is lost. The address cannot be
assigned to another pointer variable. The block cannot be de-allocated and therefore cannot be re-allocated at
any future time. The block storing the value 6 is therefore completely lost to the program and can be of no
further use. This situation is called a memory leak.
As we can see, C allows programmers to do bad things to memory. In java, all these problems are solved by
the advent of garbage collection. The operator new in java is roughly equivalent to malloc in C. When one
creates a reference (i.e. a pointer) to some memory via new, java sets up a separate internal reference to that
same memory. The java runtime system periodically checks all of its references, and if it notices that the
program no longer maintains a reference to some allocated memory, it de-allocates that memory. Thus to free
memory in java you do precisely what you should not do in C, just point the reference variable somewhere
else. Also it is not possible in Java to alter the contents of a free block, as can be done in C, since memory is
not freed until the program no longer contains references to it.
There is one more C memory allocation function of interest called calloc (contiguous allocation). We use
this function to allocate arrays on the heap. The instructions
4
int* A;
A = calloc(n, sizeof(int));
allocate a block of heap memory sufficient to store an int array of length n. Equivalently one can do
int* A;
A = malloc(n*sizeof(int));
The only difference in the two examples above is that calloc() sets its allocated memory to zero, while
malloc() does not. Note also that in both examples n can be a variable. Recall that one cannot allocate
variable length arrays on the stack. For instance int A[n] is not a valid declaration in C. As with any array,
the array name is a pointer to its zeroth element, so that the expressions A==&A[0] and *A==A[0] always
evaluate to true (i.e. non-zero). In the above examples, A is itself a stack variable, while the memory it points
to is on the heap. Pointers have a special kind of arithmetic. The expression A+1 is interpreted to be, not the
next byte after A, but the next int after A[0], namely A[1]. Thus *(A+1)==A[1], *(A+2)==A[2], etc. all
evaluate to true. This gives an alternative method for traversing an array, which is illustrated in the next
example.
#include
#include
#include
int main(int argc, char* argv[]){
int i, n;
int* A;
/* check number of arguments on the command line */
if( argc<2 ){ printf("Usage: %s positive_integer\n", argv[0]); exit(EXIT_FAILURE); } /* check that the command line argument is an integer */ /* and if so, assign it to n */ if( sscanf(argv[1], "%d", &n)<1 || n<1 ){ printf("Usage: %s positive_integer\n", argv[0]); exit(EXIT_FAILURE); } /* allocate an array of n ints on the heap */ A = calloc(n, sizeof(int)); /* initialize the array using the standard subscript notation */ for(i=0; i< 2 whitespace characters: line 3 contains: 10 alphabetic characters: afsteyYDNC 2 numeric characters: 64 1 punctuation character: & 6 whitespace characters: line 4 contains: 9 alphabetic characters: hfdjstreL 1 numeric character: 9 8 punctuation characters: *&^^%$": 1 whitespace character: Notice that in these reports the word "character" is appropriately singular or plural. Your program will contain a function called extract_chars with the prototype void extract_chars(char* s, char* a, char* d, char* p, char* w); that takes the input string s, and copies its characters into the appropriate output character arrays a (alphabetic), d (digits), p (punctuation), or w (whitespace). The output arrays will each be terminated by the null character '\0', making them into valid C strings. Function main will call extract_chars on array arguments that have been allocated from heap memory using either malloc or calloc. Before your program terminates it will free all allocated heap memory using free. It is suggested that you take the example program alphaNum.c as a starting point for your charType.c program, since much of what you need to do is illustrated there. When 6 your program is complete, test it on various input files, including its own source file. Check your program for memory leaks by using the unix program valgrind. Do % valgrind --leak-check=full charType infile outfile to run valgrind on your program. Do % valgrind –help to see some of the options to valgrind, and see the man pages for further details. Write a Makefile that creates an executable binary file called charType and includes a clean utility. Also include a target called check in your Makefile which runs valgrind on your executable as above, taking infile to be the source file charType.c itself. Use the Makefile from lab3 as a starting point. Submit the files: README, Makefile, and charType.c to the assignment name lab4. As always start early and ask for help if anything in these instructions is not clear.