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
orealloc
) i no l'allibera (utilitzantfree
), 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
Ús de Valgrind
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
Execució 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:
- Identifica la fuita de memòria en el codi.
- 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:
- Escriu un programa que contingui una fuita de memòria.
- Utilitza Valgrind per detectar la fuita de memòria.
- Corregeix la fuita de memòria basada en la sortida de Valgrind.
Solució:
-
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; }
-
Execució amb Valgrind:
valgrind --leak-check=full ./nom_del_programa
-
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
- Introducció a la Programació
- Configuració de l'Entorn de Desenvolupament
- Programa Hello World
- Sintaxi i Estructura Bàsiques
Mòdul 2: Tipus de Dades i Variables
Mòdul 3: Flux de Control
Mòdul 4: Funcions
- Introducció a les Funcions
- Arguments de Funció i Valors de Retorn
- Àmbit i Durada de les Variables
- Funcions Recursives
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
- Introducció a la Gestió d'Arxius
- Lectura i Escriptura d'Arxius
- Posicionament d'Arxius
- Gestió d'Errors en Operacions d'Arxius
Mòdul 10: Temes Avançats
- Directives del Preprocessador
- Arguments de Línia de Comandes
- Llistes d'Arguments Variables
- Multifil en C
Mòdul 11: Millors Pràctiques i Optimització
- Llegibilitat del Codi i Documentació
- Tècniques de Depuració
- Optimització del Rendiment
- Consideracions de Seguretat