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,reallocifree. - 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,callocoreallocretornenNULL: Sempre comprova si la funció ha retornatNULLper 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 
NULLals punters després d'alliberar-los per evitar accessos accidentals. - Utilitza 
callocper 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
 
