UC3M

Telematic/Audiovisual Syst./Communication Syst. Engineering

Systems Architecture

September 2017 - January 2018

17.3.  Self-assessment questions

  1. You have compiled a program with the sentence gcc -Wall -o main main.c. You execute it with Valgrind and obtain memory leaks errors, but Valgrind does not specify the code lines where these errors appear.

    • You have to indicate, in the compiling sentence, that the executable file must have detailed information, such as line numbers: gcc -l -Wall -o main main.c

    • You have to indicate, in the compiling sentence, that the executable file must have detailed information, such as line numbers: gcc -g -Wall -o main main.c

    • You have to indicate, in the Valgrind sentence, that you want line numbers printed out in the error messages output: valgrind -l --leak-check=yes ./main

    • You have to indicate, in the Valgrind sentence, that you want line numbers printed out in the error messages output: valgrind -g --leak-check=yes ./main

  2. Given the following function:

    #define SIZE 10
    
    void f(void)
    {
      int *x = malloc(SIZE * sizeof(int));
      x[SIZE-1] = 0;
    }
    • Valgrind detects a memory leak.

    • Valgrind detects a memory error (invalid write).

    • Valgrind detects a memory error (invalid read).

    • Valgrind detects an invalid free.

    • Valgrind detects no memory errors or leaks.

  3. Given the following function:

    #define SIZE 10
    
    void f(void)
    {
      char *x = malloc(SIZE * sizeof(char));
      x[SIZE] = '\0';
      free(x);
    }
    • Valgrind detects a memory leak.

    • Valgrind detects a memory error (invalid write).

    • Valgrind detects a memory error (invalid read).

    • Valgrind detects an invalid free.

    • Valgrind detects no memory errors or leaks.

  4. Given the following code:

    #define SIZE 4
    ...
      char string[SIZE] = "Test";
      printf(string);
    ...
    • Valgrind detects a memory leak.

    • Valgrind detects a memory error (invalid write).

    • Valgrind detects a memory error (invalid read).

    • Valgrind detects an invalid free.

    • Valgrind detects no memory errors or leaks.

  5. Given the following code:

    #define SIZE 6
    ...
      char string[SIZE] = "Test";
      printf(string);
    ...
    • Valgrind detects a memory leak.

    • Valgrind detects a usage of uninitialized value(s) or byte(s).

    • Valgrind detects an invalid free.

    • Valgrind detects no memory errors or leaks.

  6. Given the following program extract:

    #define SIZE 2
    void f(int *number)
    {
      int *numbers = realloc(number,SIZE*sizeof(int));
      numbers[0] = 64;
      numbers[1] = 65;
      free(numbers);
    }
    int main(void)
    {
      int *aux = malloc (sizeof(int));
      f(aux);
      free(aux);
      return 0;
    }
    • Valgrind detects a memory leak.

    • Valgrind detects a usage of uninitialized value(s) or byte(s).

    • Valgrind detects an invalid free.

    • Valgrind detects no memory errors or leaks.

  7. Given the following piece of code:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    
       //compilation in linux with gcc -pthread option
     
    #include <pthread.h>
    #include <stdio.h>
    #include <stdlib.h>       
    #include <unistd.h>
    
    struct struct_counter{
      int i;
      pthread_mutex_t mutex_i;
    };
    
    int increment_counter(struct struct_counter* counter)
    {  int to_return=0;
       pthread_mutex_unlock(&((counter)->mutex_i));
       to_return=(*counter).i++;
       pthread_mutex_unlock(&((counter)->mutex_i));
       return to_return;
     }
     
     
    void *counter_thread(void *ctr)
    {  printf("In thread: running...\n");
       sleep(1);
       printf("[_THREAD_1]Counter is %d \n", increment_counter((struct struct_counter*)ctr) );
       printf("In thread: exiting .............\n");
       pthread_exit(NULL);
    }
    
    int main(int argc, char *argv[])
    {
      struct struct_counter int_counter;
      int_counter.i=0;
      pthread_mutex_init(&int_counter.mutex_i,NULL);
      
      pthread_t threads[1];
      int rc=0;
      printf("(log) In main: creating thread %i\n", 1);
      rc = pthread_create(&threads[0], NULL, counter_thread, (struct struct_counter *)&int_counter);
      if (rc){
          printf("ERROR; return code from pthread_create() is %d\n", rc);
          exit(-1);
         }
      sleep(1);
      int res_counter=increment_counter(&int_counter);
      pthread_join(threads[0],NULL);     
      pthread_mutex_destroy(&int_counter.mutex_i);
      printf("[_MAIN___] Counter is %i \n", res_counter);
      return 0;
    }
     
    
    • Helgrind detects a race condition.

    • Helgrind warns about bad behaviour of POSIX API.

    • Helgrind detects issues in the lock ordering.

    • Helgrind does not detect any issues.

  8. Given the following piece of code

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    
       //compilation in linux with gcc -pthread option
    #include <pthread.h>
    #include <stdio.h>
    #include <stdlib.h>       
    #include <unistd.h>
    
    int increment_counter(int *counter)
     {
       (*counter)++;
       return *counter;
     }
     
     
     void *counter_thread(void *ctr)
    {  printf("In thread: running...\n");
       sleep(1);
       printf("In thread: exiting .............\n");
       pthread_exit(NULL);
    }
    
    int main(int argc, char *argv[])
    {
      int int_counter=0;
      pthread_t threads[1];
      int rc=0;
      printf("(log) In main: creating thread %i\n", 1);
      rc = pthread_create(&threads[0], NULL, counter_thread, (void *)&int_counter);
      if (rc){
          printf("ERROR; return code from pthread_create() is %d\n", rc);
          exit(-1);
         }
      sleep(1);
      int res_counter=increment_counter(&int_counter);
      pthread_join(threads[0],NULL);     
      printf("[_MAIN___] Counter is %i \n", res_counter);
      return 0;
    } 
    
    • Helgrind detects a race condition.

    • Helgrind warns about bad behaviour of POSIX API.

    • Helgrind detects issues in the lock ordering.

    • Helgrind does not detect any issues.