En aquest tema, explorarem les funcions de gestió de memòria en C, que són essencials per a la manipulació dinàmica de la memòria durant l'execució d'un programa. Aquestes funcions permeten als programadors al·locar, real·locar i alliberar memòria de manera eficient.
Objectius d'Aprenentatge
Al final d'aquest tema, hauràs de ser capaç de:
- Comprendre la importància de la gestió dinàmica de memòria.
- Utilitzar les funcions
malloc
,calloc
,realloc
ifree
. - Identificar i evitar fuites de memòria.
- Introducció a la Gestió Dinàmica de Memòria
La gestió dinàmica de memòria permet als programes al·locar memòria durant l'execució, en lloc de fer-ho només en temps de compilació. Això és especialment útil quan la quantitat de memòria necessària no es coneix prèviament.
Avantatges de la Gestió Dinàmica de Memòria
- Flexibilitat: Permet al·locar memòria segons les necessitats del programa en temps d'execució.
- Eficiència: Pot ajudar a utilitzar la memòria de manera més eficient, alliberant memòria quan ja no és necessària.
- Escalabilitat: Facilita la creació d'estructures de dades dinàmiques com llistes enllaçades, arbres, etc.
- Funcions de Gestió de Memòria
2.1 malloc
La funció malloc
(memory allocation) s'utilitza per al·locar un bloc de memòria de mida especificada. Retorna un punter al primer byte del bloc al·locat.
Sintaxi:
Exemple:
#include <stdio.h> #include <stdlib.h> int main() { int *ptr; ptr = (int*) malloc(10 * sizeof(int)); // Al·loca memòria per a 10 enters if (ptr == NULL) { printf("Error d'assignació de memòria\n"); return 1; } // Utilitza la memòria al·locada for (int i = 0; i < 10; i++) { ptr[i] = i + 1; } // Imprimeix els valors for (int i = 0; i < 10; i++) { printf("%d ", ptr[i]); } // Allibera la memòria free(ptr); return 0; }
2.2 calloc
La funció calloc
(contiguous allocation) s'utilitza per al·locar memòria per a un nombre específic d'elements de mida especificada i inicialitza tots els bytes a zero.
Sintaxi:
Exemple:
#include <stdio.h> #include <stdlib.h> int main() { int *ptr; ptr = (int*) calloc(10, sizeof(int)); // Al·loca memòria per a 10 enters i inicialitza a zero if (ptr == NULL) { printf("Error d'assignació de memòria\n"); return 1; } // Imprimeix els valors inicialitzats for (int i = 0; i < 10; i++) { printf("%d ", ptr[i]); } // Allibera la memòria free(ptr); return 0; }
2.3 realloc
La funció realloc
(reallocation) s'utilitza per canviar la mida d'un bloc de memòria prèviament al·locat.
Sintaxi:
Exemple:
#include <stdio.h> #include <stdlib.h> int main() { int *ptr; ptr = (int*) malloc(5 * sizeof(int)); // Al·loca memòria per a 5 enters if (ptr == NULL) { printf("Error d'assignació de memòria\n"); return 1; } // Reassigna la memòria per a 10 enters ptr = (int*) realloc(ptr, 10 * sizeof(int)); if (ptr == NULL) { printf("Error de reassignació de memòria\n"); return 1; } // Utilitza la memòria reassignada for (int i = 0; i < 10; i++) { ptr[i] = i + 1; } // Imprimeix els valors for (int i = 0; i < 10; i++) { printf("%d ", ptr[i]); } // Allibera la memòria free(ptr); return 0; }
2.4 free
La funció free
s'utilitza per alliberar un bloc de memòria prèviament al·locat.
Sintaxi:
Exemple:
#include <stdio.h> #include <stdlib.h> int main() { int *ptr; ptr = (int*) malloc(10 * sizeof(int)); // Al·loca memòria per a 10 enters if (ptr == NULL) { printf("Error d'assignació de memòria\n"); return 1; } // Utilitza la memòria al·locada for (int i = 0; i < 10; i++) { ptr[i] = i + 1; } // Allibera la memòria free(ptr); return 0; }
- Exercicis Pràctics
Exercici 1
Escriu un programa que al·loqui memòria per a un array de 20 enters, inicialitzi els valors a 0 utilitzant calloc
, i imprimeixi els valors.
Solució:
#include <stdio.h> #include <stdlib.h> int main() { int *arr; arr = (int*) calloc(20, sizeof(int)); if (arr == NULL) { printf("Error d'assignació de memòria\n"); return 1; } for (int i = 0; i < 20; i++) { printf("%d ", arr[i]); } free(arr); return 0; }
Exercici 2
Escriu un programa que al·loqui memòria per a un array de 5 enters, després reassigni la memòria per a 10 enters, inicialitzi els nous elements a 0, i imprimeixi tots els valors.
Solució:
#include <stdio.h> #include <stdlib.h> int main() { int *arr; arr = (int*) malloc(5 * sizeof(int)); if (arr == NULL) { printf("Error d'assignació de memòria\n"); return 1; } arr = (int*) realloc(arr, 10 * sizeof(int)); if (arr == NULL) { printf("Error de reassignació de memòria\n"); return 1; } for (int i = 5; i < 10; i++) { arr[i] = 0; } for (int i = 0; i < 10; i++) { printf("%d ", arr[i]); } free(arr); return 0; }
- Errors Comuns i Consells
Errors Comuns
- No comprovar si
malloc
,calloc
orealloc
retornenNULL
: Sempre comprova si la funció ha retornatNULL
per evitar accessos a memòria no vàlida. - No alliberar memòria amb
free
: No alliberar memòria pot causar fuites de memòria, que poden esgotar els recursos del sistema. - Utilitzar memòria després d'alliberar-la: Accedir a memòria després d'haver-la alliberat pot causar comportaments indefinits.
Consells
- Inicialitza sempre els punters: Assigna
NULL
als punters després d'alliberar-los per evitar accessos accidentals. - Utilitza
calloc
per inicialitzar memòria a zero: Això pot evitar errors en la inicialització de dades.
Conclusió
En aquest tema, hem après sobre les funcions de gestió de memòria en C, incloent malloc
, calloc
, realloc
i free
. Hem vist com utilitzar aquestes funcions per al·locar, real·locar i alliberar memòria dinàmica, i hem practicat amb alguns exemples i exercicis. La gestió adequada de la memòria és crucial per escriure programes eficients i lliures d'errors.
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