UC3M

Grado en Ing. Telemática/Sist. Audiovisuales/Sist. de Comunicaciones

Arquitectura de Sistemas

Septiembre 2017 - Enero 2018

17.3. Preguntas de autoevaluación

  1. Has compilado un programa con la sentencia gcc -Wall -o main main.c. Lo ejecutas con Valgrind con la sentencia valgrind --leak-check=yes ./main, y te advierte de fugas de memoria pero no te indica las líneas del código donde las ha encontrado.

    • Hay que indicar en la sentencia de compilación que se incluya información detallada en el fichero ejecutable, como el número de línea: gcc -l -Wall -o main main.c

    • Hay que indicar en la sentencia de compilación que se incluya información detallada en el fichero ejecutable, como el número de cada línea: gcc -g -Wall -o main main.c

    • Hay que indicar en la sentencia de Valgrind que saque por pantalla el número de línea donde encuentre errores. valgrind -l --leak-check=yes ./main

    • Hay que indicar en la sentencia de Valgrind que saque por pantalla el número de línea donde encuentre errores. valgrind -g --leak-check=yes ./main

  2. Dada la siguiente función:

    #define SIZE 10
    
    void f(void)
    {
      int *x = malloc(SIZE * sizeof(int));
      x[SIZE-1] = 0;
    }
    • Valgrind advierte de una fuga de memoria.

    • Valgrind advierte de un error de escritura en memoria.

    • Valgrind advierte de un error de lectura en memoria.

    • Valgrind advierte de una liberación inválida ("invalid free").

    • No hay fugas ni errores de memoria en esa función.

  3. Dada la siguiente función:

    #define SIZE 10
    
    void f(void)
    {
      char *x = malloc(SIZE * sizeof(char));
      x[SIZE] = '\0';
      free(x);
    }
    • Valgrind advierte de una fuga de memoria.

    • Valgrind advierte de un error de escritura en memoria.

    • Valgrind advierte de un error de lectura en memoria.

    • Valgrind advierte de una liberación inválida ("invalid free").

    • No hay fugas ni errores de memoria en esa función.

  4. Dado el siguiente trozo de código:

    #define SIZE 4
    ...
      char string[SIZE] = "Test";
      printf(string);
    ...
    • Valgrind advierte de una fuga de memoria.

    • Valgrind advierte de un error de escritura en memoria.

    • Valgrind advierte de un error de lectura en memoria.

    • Valgrind advierte de una liberación inválida ("invalid free").

    • No hay fugas ni errores de memoria en ese código.

  5. Dado el siguiente trozo de código:

    #define SIZE 6
    ...
      char string[SIZE] = "Test";
      printf(string);
    ...
    • Valgrind advierte de una fuga de memoria.

    • Valgrind advierte de uso de valor(es) o byte(s) sin inicializar.

    • Valgrind advierte de una liberación inválida ("invalid free").

    • No hay fugas ni errores de memoria en ese código.

  6. Dado el siguiente extracto de un programa:

    #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 advierte de una fuga de memoria.

    • Valgrind advierte de uso de valor(es) o byte(s) sin inicializar.

    • Valgrind advierte de una liberación inválida ("invalid free").

    • No hay fugas ni errores de memoria en ese código.

  7. Dado el siguiente trozo de código:

    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 advierte de condición de carrera.

    • Helgrind advierte de mal uso del API POSIX.

    • Helgrind detecta problema en el orden de los cerrojos.

    • Helgrind no detecta problemas.

  8. Dado el siguiente trozo de código

    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 advierte de condición de carrera.

    • Helgrind advierte de mal uso del API POSIX.

    • Helgrind detecta problema en el orden de los cerrojos.

    • Helgrind no detecta problemas.