C Academy · Pelajaran

Membebaskan dan Mengelakkan Kebocoran

Bersihkan dengan betul.

Pelajaran 4 daripada 413 langkah

Membebaskan dan Mengelakkan Kebocoran ialah pelajaran C Academy percuma di CoddyKit. Ini ialah pelajaran 4 daripada 4. Anda boleh membaca keseluruhan pelajaran di bawah secara percuma — kemudian berlatih secara praktikal dalam pelayar menggunakan penyunting kod terbina dalam dan tutor kecerdasan buatan 24/7. Pelajaran ini merupakan sebahagian daripada laluan pembelajaran C Academy, dan kemajuan anda disegerakkan merentas web serta aplikasi CoddyKit. Kursus C Academy merangkumi sejumlah 4 pelajaran.

Setiap malloc Memerlukan free

Memori timbunan kekal ditempah sehingga anda melepaskannya dengan free. Jika anda kehilangan satu-satunya penuding kepada blok tanpa membebaskannya, memori itu bocor.

Kebocoran terkumpul dari semasa ke semasa dan boleh menghabiskan memori dalam program yang berjalan lama.

int *a = malloc(100 * sizeof(*a));
/* ... use a ... */
free(a);

Perkara Sebenar yang Dilakukan oleh free

free(p) memulangkan blok kepada pengagih supaya blok itu boleh digunakan semula. Ia tidak mengubah nilai p itu sendiri.

Selepas free, p masih menunjuk kepada alamat lama yang kini tidak sah. Menggunakannya menghasilkan tingkah laku tidak ditakrifkan.

free(p);
/* p is now a dangling pointer */

Perangkap Penuding Tergantung

Menggunakan penuding selepas membebaskannya ialah ralat penggunaan-selepas-bebas. Ia mungkin kelihatan berfungsi, kemudian merosakkan data atau ranap secara tidak menentu.

Perlindungan mudah ialah menetapkan penuding kepada NULL sejurus selepas membebaskannya.

free(a);
a = NULL;   /* now misuse is a clean NULL deref, easier to catch */

Bebas Dua Kali ialah Tidak Ditakrifkan

Memanggil free dua kali pada blok yang sama merosakkan keadaan dalaman pengagih dan sering menyebabkan ranap.

Menetapkan penuding kepada NULL selepas free pertama membantu kerana free(NULL) selamat secara jelas dan tidak melakukan apa-apa.

free(a);
a = NULL;
free(a);   /* free(NULL) is a harmless no-op */

Bebaskan Hanya Perkara yang Diperuntukkan dengan malloc

Hantar kepada free hanya penuding yang datang daripada malloc, calloc atau realloc.

Membebaskan alamat pemboleh ubah tindanan, literal rentetan atau penuding ke bahagian tengah blok menghasilkan tingkah laku tidak ditakrifkan.

int x = 5;
/* free(&x);   WRONG: x is on the stack */
int *p = malloc(sizeof(int));
free(p);        /* correct */

Kebocoran akibat Pemulangan Awal

Kebocoran yang biasa berlaku: anda membuat peruntukan, kemudian menemui laluan ralat yang memulangkan kawalan sebelum pembebasan dilakukan. Blok itu hilang.

Pastikan setiap laluan keluar yang memiliki memori membebaskannya terlebih dahulu.

int *a = malloc(n * sizeof(*a));
if (something_failed) {
    free(a);   /* don't forget this before returning */
    return -1;
}

Program Peruntukan-dan-Pembebasan yang Kemas

Program ini memperuntukkan, menggunakan dan membebaskan memori pada setiap laluan tanpa membocorkan apa-apa.

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

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

Membebaskan Peruntukan Bersarang

Jika sesebuah blok mengandungi penuding kepada blok lain, bebaskan blok di dalam terlebih dahulu, kemudian blok di luar.

Membebaskan blok luar dahulu akan menyebabkan alamat blok dalam hilang dan blok tersebut bocor.

for (size_t i = 0; i < rows; i++)
    free(grid[i]);   /* free each row first */
free(grid);          /* then the array of pointers */

Satu Pemilik bagi Setiap Blok

Tentukan bahagian kod anda yang memiliki setiap peruntukan dan bertanggungjawab untuk membebaskannya.

Jika dua penuding merujuk blok yang sama dan kedua-duanya membebaskannya, pembebasan berganda berlaku. Pemilikan yang jelas menghalangnya.

Mengesan Kebocoran dengan Alat

Anda tidak perlu mencari kebocoran dengan mata kasar. Alat seperti valgrind atau AddressSanitizer melaporkan kebocoran dan pembebasan tidak sah berserta nombor baris.

Kompil dengan -g dan jalankan program menggunakan alat tersebut untuk melihat dengan tepat perkara yang tidak dibebaskan.

/* gcc -g -fsanitize=address prog.c && ./a.out */
/* or: valgrind --leak-check=full ./a.out */

Bebaskan Mengikut Susunan Songsang Persediaan

Amalan yang boleh dipercayai: dalam fungsi yang memperoleh beberapa sumber, lepaskan sumber tersebut mengikut susunan songsang pemerolehannya.

Ini mencerminkan cara kebergantungan dibina dan menjadikan pembersihan lebih mudah dijangka.

char *buf = malloc(64);
int  *idx = malloc(64 * sizeof(int));
/* ... use them ... */
free(idx);   /* free last-acquired first */
free(buf);

Semakan Pantas

Uji pemahaman anda tentang pembebasan memori.

Imbas Kembali

Padankan setiap peruntukan dengan tepat satu free pada setiap laluan kod.

Elakkan penuding tergantung dan pembebasan berganda dengan menetapkan penuding kepada NULL selepas pembebasan. Bebaskan peruntukan bersarang bermula dari bahagian dalam, berikan setiap blok seorang pemilik, dan gunakan valgrind atau ASan untuk mengesan kebocoran. Kini anda mempunyai set alat lengkap untuk tatasusunan dinamik.

Percuma untuk bermula

Pelajari C dengan tutor kecerdasan buatan — percuma

Tulis dan jalankan kod sebenar dalam pelayar anda, dapatkan bantuan segera daripada tutor kecerdasan buatan yang tersedia 24/7, dan sambung semula dari tempat anda berhenti di web atau dalam aplikasi.

Kursus
39
Pelajaran
144

Soalan Lazim

Adakah pelajaran “Membebaskan dan Mengelakkan Kebocoran” percuma?

Ya — teks penuh “Membebaskan dan Mengelakkan Kebocoran” boleh dibaca secara percuma di web ini. Untuk berlatih secara interaktif menggunakan penyunting kod terbina dalam dan tutor kecerdasan buatan 24/7, serta membuka kunci baki kursus C Academy, tingkat taraf kepada CoddyKit PRO. Kursus C Academy merangkumi sejumlah 4 pelajaran.

Apakah yang akan saya pelajari dalam “Membebaskan dan Mengelakkan Kebocoran”?

Bersihkan dengan betul. Anda berlatih C Academy menggunakan kod praktikal yang dijalankan terus dalam pelayar, manakala tutor kecerdasan buatan 24/7 menjawab soalan anda semasa anda mengikuti pelajaran.

Adakah saya memerlukan pengalaman untuk memulakan C Academy?

Tiada pengalaman terdahulu diperlukan. Pembelajaran C Academy di CoddyKit disusun untuk pelajar daripada peringkat pemula hingga lanjutan, jadi anda boleh bermula di sini atau dari awal dan belajar mengikut kadar anda sendiri. Ini ialah pelajaran 4 daripada 4.

Berapa lamakah pelajaran “Membebaskan dan Mengelakkan Kebocoran” diambil?

Kebanyakan pelajaran CoddyKit mengambil masa kira-kira 5–10 minit. Setiap pelajaran ringkas dan interaktif, jadi anda boleh membuat kemajuan secara berterusan dan menyambung tepat dari tempat anda berhenti di web atau aplikasi.

Bolehkah saya menulis dan menjalankan kod dalam pelajaran C Academy ini?

Ya. Setiap pelajaran C Academy menyertakan penyunting kod terbina dalam, jadi anda boleh menulis dan menjalankan kod sebenar terus dalam pelayar serta menerima maklum balas kecerdasan buatan serta-merta — tanpa memerlukan persediaan setempat.

Semua pelajaran dalam kursus ini

  1. Memperuntukkan Tatasusunan
  2. Membesar dengan realloc
  3. Jenis Vektor Boleh Guna Semula
  4. Membebaskan dan Mengelakkan Kebocoran
← Kembali ke C Academy