Memori · Pelajaran 11 dari 12
Memori dinamis dengan malloc dan free
10 menit baca · BelajarCode
Array biasa harus tahu ukurannya saat kode ditulis. Bagaimana jika banyak datanya baru diketahui saat program berjalan? Jawabannya memori dinamis.
| Stack | Heap | |
|---|---|---|
| Isinya | Variabel lokal dan parameter fungsi | Memori yang diminta dengan malloc |
| Dikelola oleh | Otomatis, dibebaskan saat fungsi selesai | Programmer, harus dibebaskan dengan free |
| Ukuran | Kecil dan terbatas | Jauh lebih besar |
1#include <stdio.h>2#include <stdlib.h>34int main(void) {5 int n;6 if (scanf("%d", &n) != 1 || n <= 0) return 1;78 int *nilai = malloc(n * sizeof(int));9 if (nilai == NULL) {10 printf("Memori tidak cukup\n");11 return 1;12 }1314 long long total = 0;15 for (int i = 0; i < n; i++) {16 if (scanf("%d", &nilai[i]) != 1) {17 free(nilai);18 return 1;19 }20 total += nilai[i];21 }22 printf("Rata-rata %d nilai: %.2f\n", n, (double)total / n);2324 free(nilai);25 nilai = NULL;26 return 0;27}4 80 92 75 88
Rata-rata 4 nilai: 83.75
malloc(n * sizeof(int))meminta memori untuk n bilangan int dan mengembalikan alamatnya.mallocmengembalikanNULLjika gagal. Selalu periksa sebelum memakai.free(nilai)mengembalikan memori ke sistem. Setiapmallocharus punya pasanganfree.- Memberi
NULLsetelahfreemencegah pointer itu terpakai lagi tanpa sengaja.
Memperbesar memori dengan realloc
1#include <stdio.h>2#include <stdlib.h>34int main(void) {5 int kapasitas = 2, banyak = 0;6 int *data = malloc(kapasitas * sizeof(int));7 if (data == NULL) return 1;89 for (int x = 1; x <= 10; x++) {10 if (banyak == kapasitas) {11 kapasitas *= 2;12 int *baru = realloc(data, kapasitas * sizeof(int));13 if (baru == NULL) {14 free(data);15 return 1;16 }17 data = baru;18 printf("Kapasitas diperbesar menjadi %d\n", kapasitas);19 }20 data[banyak++] = x * x;21 }22 printf("Data terakhir: %d, banyak: %d\n", data[banyak - 1], banyak);23 free(data);24 return 0;25}Kapasitas diperbesar menjadi 4 Kapasitas diperbesar menjadi 8 Kapasitas diperbesar menjadi 16 Data terakhir: 100, banyak: 10
Kapasitas digandakan setiap kali penuh. Strategi ini juga dipakai list di Python dan ArrayList di Java, sehingga menambah data rata-rata tetap cepat. Hasil realloc disimpan ke pointer sementara dulu, supaya memori lama tidak hilang jika realloc gagal.
Tiga kesalahan memori yang klasik
- Kebocoran memori (memory leak): lupa free. Program yang berjalan lama terus memakan memori. - Dangling pointer: memakai pointer setelah memorinya di-free. - Double free: memanggil free dua kali untuk memori yang sama. Alat seperti Valgrind atau opsi kompilasi -fsanitize=address membantu menemukan kesalahan-kesalahan ini.
Cek pemahaman
Kenapa hasil realloc sebaiknya disimpan ke pointer sementara lebih dulu?
Latihan
Menyalin string ke heap
Tulis fungsi char *salin(const char *s) yang mengalokasikan memori secukupnya di heap, menyalin string s ke sana, lalu mengembalikan alamatnya. Jangan lupa ruang untuk '\0'.
Pembahasan
1#include <stdio.h>2#include <stdlib.h>3#include <string.h>45char *salin(const char *s) {6 size_t panjang = strlen(s);7 char *hasil = malloc(panjang + 1);8 if (hasil == NULL) return NULL;9 memcpy(hasil, s, panjang + 1);10 return hasil;11}1213int main(void) {14 char *teks = salin("Struktur Data");15 if (teks == NULL) return 1;16 teks[0] = 's';17 printf("%s\n", teks);18 free(teks);19 return 0;20}struktur Data
panjang + 1 menyisakan satu byte untuk karakter '\0'. Lupa satu byte ini adalah kesalahan yang sangat umum. Pemanggil fungsi bertanggung jawab memanggil free.
Jalankan contoh kode di pelajaran ini tanpa instalasi lewat compiler C online.