CSPP 51081 - Tutorial #6

Files for today : tut6.zip

Declaring variables with the const qualifier

We can use the const qualifier to indicate that the value of a variable cannot be changed after it is declared:

  int my_fun() {

    const int i = 42;

    ...

    i++; /* compiler error */

  }

We can use const to modify pointer declarations. Here, order matters:

  const int *       p;   /* pointer to an const integer */
        int * const p;   /* const pointer to an int */

TIP: Read variable declarations from right to left.

We most often see const in function declarations, for example:

  char *strdup(const char *s); /* from string.h */

  const struct point * get_max();

With implicit type conversion, a "non-const" variable can be converted to a const:

  char * str = "Hello!";
  char * dup = strdup(str);
 

But not vice-versa:

  const char * str1 = "Hello!";
  char * str2 = str1; /* compiler error */
 

Reviewing malloc

Recall that malloc is used to allocate memoery dynamically, at runtime, from the heap.

  int * pi = (int *) malloc(100 * sizeof(int)); /* Array of 100 integers */

Quick review: ex0_malloc.c   Text

How would we complete this function using malloc?

  char * create_string() /* get string from user, return copy */
  {
    char buf[256];
    scanf("%s",buf);
    char * res = ...   /* INCOMPLETE */

    sprintf(res ,"%s",buf);
    return res;
  }

Using malloc with structures

Up to now we've mostly seen malloc used to create strings. Dynamic memory allocation will also be very useful with structures.

ex1_emp.c   Text

Why is free called three times in the function free_employee?.

What is wrong with this line of code?

struct point * p = (struct point *)malloc(sizeof(struct point *));

Recall that the -> operator is used with pointers-to-structures.

Arrayrs of structures and pointers-to-structures

We may also want to use malloc with arrays of structures

  struct point * point_arr = (struct point *) malloc(NUM_PTS * sizeof(struct point ));

ex2_array.c   Text

and arrays of pointers-to-structures:

  struct point * point_arr[NUM_PTS];
  ...
 
  for (i=0;i <NUM_PTS;i++) {
    point_arr[i] = (struct point *) malloc (sizeof(struct point));
    ...
  }

ex3_array.c   Text

TODO: add code to free memory in one of the above examples.

Another function for dynamic memory allocation - calloc

calloc allocates memory for an array of nmemb elements of size bytes each and returns a pointer to the allocated memory.

void * calloc(size_t nmemb, size_t size);

Unlike, malloc, the memory is set to zero. (Why would this matter?)

The function bzero can also be used to clear memory:

void bzero(void *s, size_t n);

We can rewrite example 2 with calloc:

    struct point * point_arr = (struct point *) calloc(NUM_PTS, sizeof(struct point ));

Memory leaks and free

  void free(void *ptr);

Note that free does not change the value of the argument ptr

ex6_leak.c   Text

Memory corruption

A memory corruption occurs when memory is altered inadvertantly.

ex7_corr.c   Text