Introducció

En aquest tema, explorarem les fuites de memòria, un problema comú en la programació en C, i les tècniques per depurar-les. Les fuites de memòria ocorren quan un programa reserva memòria dinàmica però no l'allibera correctament, la qual cosa pot conduir a un ús excessiu de memòria i, eventualment, a la fallida del programa.

Conceptes Clau

Què és una Fuita de Memòria?

  • Definició: Una fuita de memòria es produeix quan un programa reserva memòria dinàmica (utilitzant funcions com malloc, calloc o realloc) i no l'allibera (utilitzant free), fent que la memòria reservada no estigui disponible per a altres processos.
  • Impacte: Les fuites de memòria poden causar que un programa utilitzi més memòria de la necessària, la qual cosa pot conduir a una disminució del rendiment i, en casos extrems, a la fallida del sistema.

Identificació de Fuites de Memòria

  • Símptomes: Un ús creixent de memòria durant l'execució del programa, fallides inesperades, i missatges d'error relacionats amb la memòria.
  • Eines: Hi ha diverses eines disponibles per identificar fuites de memòria, com Valgrind, AddressSanitizer, i altres depuradors de memòria.

Exemples Pràctics

Exemple de Fuita de Memòria

#include <stdio.h>
#include <stdlib.h>

void createMemoryLeak() {
    int *ptr = (int *)malloc(sizeof(int) * 10);
    // No s'allibera la memòria reservada
}

int main() {
    createMemoryLeak();
    return 0;
}

Explicació: En aquest exemple, la funció createMemoryLeak reserva memòria per a un array de 10 enters, però no l'allibera. Això resulta en una fuita de memòria.

Solució a la Fuita de Memòria

#include <stdio.h>
#include <stdlib.h>

void createMemoryLeak() {
    int *ptr = (int *)malloc(sizeof(int) * 10);
    // S'allibera la memòria reservada
    free(ptr);
}

int main() {
    createMemoryLeak();
    return 0;
}

Explicació: Aquí, hem afegit la funció free(ptr) per alliberar la memòria reservada, eliminant així la fuita de memòria.

Eines de Depuració

Valgrind

Valgrind és una eina potent per detectar fuites de memòria i altres errors relacionats amb la memòria.

Instal·lació de Valgrind

sudo apt-get install valgrind

Ús de Valgrind

valgrind --leak-check=full ./nom_del_programa

Explicació: Aquesta comanda executa el programa sota Valgrind, que informarà de qualsevol fuita de memòria detectada.

AddressSanitizer

AddressSanitizer és una altra eina popular per detectar errors de memòria.

Compilació amb AddressSanitizer

gcc -fsanitize=address -g -o nom_del_programa nom_del_programa.c

Execució del Programa

./nom_del_programa

Explicació: Compilant el programa amb l'opció -fsanitize=address, AddressSanitizer detectarà i informarà de qualsevol fuita de memòria durant l'execució.

Exercicis Pràctics

Exercici 1: Identificar i Corregir una Fuita de Memòria

Codi Inicial:

#include <stdio.h>
#include <stdlib.h>

void memoryLeakExample() {
    char *str = (char *)malloc(50 * sizeof(char));
    // No s'allibera la memòria reservada
}

int main() {
    memoryLeakExample();
    return 0;
}

Tasques:

  1. Identifica la fuita de memòria en el codi.
  2. Corregeix la fuita de memòria alliberant la memòria reservada.

Solució:

#include <stdio.h>
#include <stdlib.h>

void memoryLeakExample() {
    char *str = (char *)malloc(50 * sizeof(char));
    // S'allibera la memòria reservada
    free(str);
}

int main() {
    memoryLeakExample();
    return 0;
}

Exercici 2: Utilitzar Valgrind per Detectar Fuites de Memòria

Tasques:

  1. Escriu un programa que contingui una fuita de memòria.
  2. Utilitza Valgrind per detectar la fuita de memòria.
  3. Corregeix la fuita de memòria basada en la sortida de Valgrind.

Solució:

  1. Codi amb Fuita de Memòria:

    #include <stdio.h>
    #include <stdlib.h>
    
    void memoryLeakExample() {
        int *arr = (int *)malloc(100 * sizeof(int));
        // No s'allibera la memòria reservada
    }
    
    int main() {
        memoryLeakExample();
        return 0;
    }
    
  2. Execució amb Valgrind:

    valgrind --leak-check=full ./nom_del_programa
    
  3. Codi Corregit:

    #include <stdio.h>
    #include <stdlib.h>
    
    void memoryLeakExample() {
        int *arr = (int *)malloc(100 * sizeof(int));
        // S'allibera la memòria reservada
        free(arr);
    }
    
    int main() {
        memoryLeakExample();
        return 0;
    }
    

Resum

En aquest tema, hem après què són les fuites de memòria, com identificar-les i com utilitzar eines com Valgrind i AddressSanitizer per depurar-les. També hem vist exemples pràctics i exercicis per reforçar els conceptes apresos. Assegurar-se que la memòria es gestiona correctament és crucial per a la robustesa i l'eficiència dels programes en C.

Curs de Programació en C

Mòdul 1: Introducció al C

Mòdul 2: Tipus de Dades i Variables

Mòdul 3: Flux de Control

Mòdul 4: Funcions

Mòdul 5: Arrays i Strings

Mòdul 6: Punteres

Mòdul 7: Estructures i Unions

Mòdul 8: Assignació Dinàmica de Memòria

Mòdul 9: Gestió d'Arxius

Mòdul 10: Temes Avançats

Mòdul 11: Millors Pràctiques i Optimització

Mòdul 12: Projecte i Avaluació Final

© Copyright 2024. Tots els drets reservats