0Pricing
C Academy · Lezione

Memory leak

Individuare ed evitare le perdite

Memory leak è una lezione C Academy gratuita su CoddyKit. Questa è la lezione 3 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento C Academy, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso C Academy include 4 lezioni in totale.

Che cos'è una perdita di memoria

Si verifica una perdita di memoria quando si alloca memoria nello heap senza mai liberarla e si perde l'unico puntatore che la identifica.

La memoria rimane riservata fino alla terminazione del programma, sprecando risorse.

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

int main(void) {
    int *p = malloc(sizeof(int));
    *p = 5;
    printf("%d\n", *p);
    free(p);
    return 0;
}

Perdere il puntatore

La perdita classica si verifica quando si sovrascrive un puntatore con una nuova allocazione prima di liberare quella vecchia.

Il primo blocco diventa irraggiungibile.

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

int main(void) {
    int *p = malloc(sizeof(int));
    free(p);
    p = malloc(sizeof(int));
    *p = 10;
    printf("%d\n", *p);
    free(p);
    return 0;
}

Perdite nei cicli

Allocare all'interno di un ciclo senza liberare la memoria a ogni iterazione fa aumentare rapidamente la perdita.

La soluzione consiste nel liberare la memoria prima che l'iterazione successiva sovrascriva il puntatore.

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

int main(void) {
    for (int i = 0; i < 3; i++) {
        int *p = malloc(sizeof(int));
        *p = i;
        printf("%d ", *p);
        free(p);
    }
    printf("\n");
    return 0;
}

I return anticipati causano perdite

Un return anticipato dopo un'allocazione può saltare la pulizia. Libere sempre la memoria lungo ogni percorso di uscita.

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

int process(int bad) {
    int *p = malloc(sizeof(int));
    if (bad) {
        free(p);
        return -1;
    }
    *p = 42;
    int r = *p;
    free(p);
    return r;
}

int main(void) {
    printf("%d\n", process(0));
    return 0;
}

Lo schema di pulizia con goto

Una singola etichetta di pulizia raggiunta con goto garantisce un unico punto in cui liberare tutto, evitando chiamate free duplicate.

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

int main(void) {
    int rc = 1;
    int *p = malloc(sizeof(int));
    if (!p) goto done;
    *p = 7;
    printf("%d\n", *p);
    rc = 0;
done:
    free(p);
    return rc;
}

Associare ogni allocazione

La regola più semplice è: per ogni malloc, calloc o realloc deve esserci esattamente un free corrispondente.

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

int main(void) {
    char *a = malloc(8);
    char *b = calloc(4, sizeof(char));
    a[0] = 'x';
    printf("%c %d\n", a[0], b[0]);
    free(a);
    free(b);
    return 0;
}

Liberare allocazioni annidate

Se una struttura possiede memoria nello heap, liberi i puntatori interni prima di liberare il blocco esterno.

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

typedef struct {
    int *data;
} Box;

int main(void) {
    Box *b = malloc(sizeof(Box));
    b->data = malloc(3 * sizeof(int));
    b->data[0] = 1;
    printf("%d\n", b->data[0]);
    free(b->data);
    free(b);
    return 0;
}

Liberare un array di puntatori

Quando alloca un array di puntatori e ogni elemento è a sua volta un'allocazione, liberi prima ogni elemento e poi l'array.

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

int main(void) {
    int n = 3;
    int **rows = malloc(n * sizeof(int *));
    for (int i = 0; i < n; i++) {
        rows[i] = malloc(2 * sizeof(int));
        rows[i][0] = i;
    }
    for (int i = 0; i < n; i++) free(rows[i]);
    free(rows);
    printf("freed all rows\n");
    return 0;
}

Disciplina della proprietà

Stabilisca chi possiede ogni allocazione ed è responsabile di liberarla. Documenti questa informazione, così chi chiama sa se deve liberare un puntatore restituito.

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

char *make_greeting(void) {
    char *s = malloc(6);
    s[0]='h'; s[1]='i'; s[2]='\0';
    return s;
}

int main(void) {
    char *g = make_greeting();
    printf("%s\n", g);
    free(g);
    return 0;
}

Strumenti per individuare le perdite

Strumenti come Valgrind e AddressSanitizer segnalano le perdite monitorando ogni allocazione e mostrando quali non sono mai state liberate.

Sono essenziali per verificare i programmi reali.

Un ciclo di vita pulito dell'allocazione

In sintesi: allochi, controlli, utilizzi, liberi lungo ogni percorso e imposti il puntatore su null. In questo modo i programmi non presentano perdite di memoria.

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

int main(void) {
    int *p = malloc(4 * sizeof(int));
    if (!p) return 1;
    for (int i = 0; i < 4; i++) p[i] = i + 1;
    int sum = 0;
    for (int i = 0; i < 4; i++) sum += p[i];
    printf("sum = %d\n", sum);
    free(p);
    p = NULL;
    return 0;
}

Verifica rapida

Verifichi la Sua comprensione delle perdite di memoria.

Riepilogo

Ha imparato a prevenire le perdite di memoria:

  • Associ ogni allocazione a esattamente un free.
  • Libere la memoria lungo ogni percorso di uscita, inclusi i return anticipati e gli errori.
  • Libere le allocazioni annidate e quelle di array di puntatori dall'interno verso l'esterno.
  • Definisca chiaramente la proprietà e utilizzi strumenti come Valgrind per verificare il codice.

Domande Frequenti

La lezione «Memory leak» è gratuita?

Sì — il testo completo di «Memory leak» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso C Academy, passa a CoddyKit PRO. Il corso C Academy include 4 lezioni in totale.

Cosa imparerò in «Memory leak»?

Individuare ed evitare le perdite Eserciti C Academy con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.

Ho bisogno di esperienza per iniziare C Academy?

Non è richiesta alcuna esperienza precedente. C Academy su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 3 di 4.

Quanto tempo richiede la lezione «Memory leak»?

La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.

Posso scrivere ed eseguire codice in questa lezione C Academy?

Sì. Ogni lezione C Academy include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.

Tutte le lezioni di questo corso

  1. malloc e free
  2. calloc e realloc
  3. Memory leak
  4. Dangling pointer
← Torna a C Academy