UC3M

Telematic/Audiovisual Syst./Communication Syst. Engineering

Systems Architecture

September 2017 - January 2018

6.11.  Problems about memory leaks

The following problems assume that you are familiar with the system calls to allocate and deallocate dynamic memory.

  1. Consider the following C program:

    #define SIZE 100
    int main(int argc, char *argv[]) 
    {
      int i, j;
      int *ptr;
    
      for (i = 0; i < SIZE; i++) 
      {
        ptr = (int *)malloc(SIZE * sizeof(int));
        for (j = 0; j < SIZE; j++) 
        {
          ptr[j] = j;
        }
      }
      ptr = NULL;
    }

    How many memory leaks has this code fragment? How much memory leaks?

  2. A programmer works with a linked list of words. Each element has a pointer to a chain and a pointer to the next. The list is represented by a pointer to its first element. The code for the function to delete a list is the following:

    struct list_node 
    {
      char *word;
      struct list_node *next;
    };
    
    void delete(struct list_node *l) 
    {
      struct list_node *tmp;
      while (l->next != NULL) 
      {
        tmp = l;
        free(l->word);
        l = l->next;
        free(l);
      }
    }

    After using a program to detect memory leaks, the report says that there are certain memory blocks not freed. The programmer has detected that the problem is in this function, but where exactly? (Hint: Draw first an example with a linked list and see how the function performs the deletion)

    What happens if an empty list is deleted? This means that l is NULL.

  3. A program needs to manipulate a binary tree (every node has two and only two children). The data structure used is the following:

    struct tree_node 
    {
      int value;
      struct tree_node *left;
      struct tree_node *right;
    };

    A node with no children is represented with the two pointers to NULL.

    1. Write a function that given an integer it returns a terminal node with the given value stored. The function must create that node. The function prototype is the following:

      struct tree_node *node(int v);
    2. Write a function that given an integer and two pointers to nodes (already created), returns a new node with the integer stored as value and the two pointers as children. The function prototype is the following:

      struct tree_node *create_node(int v, struct tree_node *left, struct tree_node *right);
    3. Write now the main function that using the two previous functions created the tree shown in the following figure:

    4. Write a function that given a pointer to a node, frees the space it occupies. No operation is done on the children, they are assumed to be already deallocated. The function prototype is:

      void delete(struct tree_node *t);
    5. Using the previous function, write another function that given a pointer to a node, deallocates all the nodes in that tree (watch out, this is not a trivial function, if you cannot write it, check with us). The function prototype is:

      void delete_tree(struct tree_node *t);
  4. An application that executes in your mobile phone has the following data structure already created and based in the following definitions:

    struct vendor 
    {
      char *vendor_name;
      int installation_date;
      int price;
    };
    struct program 
    {
      char *path;
      struct stats 
      {
        int uses;
        int last_use;
      } statistics;
      struct vendor *vendor_info;
    };
    struct program *installed_applications;
    int number_of_installed_applications;

    The program has dynamically reserved (through malloc) an array with as many data structures of type program as indicated in the variable number_of_installed_applications and has stored this pointer in installed_applications. Each element of type struct program has its fields path and vendor_info dynamically allocated.In a similar way, each element of type struct vendor has its field vendorname dynamically allocated

    Write a function that receives a pointer of type struct program * to a table like the one stored in installed_applications and its size as an integer, and fees the space occupied by the data type. The prototype of this function is:

    void delete(struct program *table, int size);