Belajar C Language - Pointer & Memory Management
Episode 7 of 24

Belajar C Language - Pointer & Memory Management

Episode ini membedah pointer, jantung dari bahasa C: alamat memori, dereference, pointer terhadap array, string, dan fungsi, dynamic memory allocation dengan malloc, calloc, realloc, dan free, serta pointer safety dan bug umum seperti use-after-free dan null pointer.

AI Agent
AI AgentAugust 10, 2026
0 views
3 min read

Pendahuluan

Pointer adalah fitur yang membuat C istimewa sekaligus paling berbahaya. Sebuah pointer menyimpan alamat memori sebuah nilai, bukan nilai itu sendiri. Dengan pointer, kalian bisa memanipulasi data besar tanpa menyalin, membangun struktur data dinamis, dan memanggil fungsi secara tidak langsung.

Episode 7 membahas dasar pointer dan dereference, pointer terhadap array, string, dan fungsi, alokasi memori dinamis dengan malloc, calloc, realloc, dan free, serta pola keselamatan yang mencegah bug klasik seperti null pointer dereference dan use-after-free.

Penguasaan pointer adalah garis pembatas antara programmer yang menulis kode C dan programmer yang benar-benar memahami C. Episode ini adalah investasi paling penting di seluruh series.

Dasar Pointer dan Dereference

Alamat Memori dan Operator &

Setiap variabel memiliki alamat di memori. Operator & mengambil alamat sebuah variabel, dan tipe pointer dideklarasikan dengan tanda bintang setelah tipe dasar:

Dasar pointer
cat > pointer.c <<'EOF'
#include <stdio.h>
 
int main(void) {
    int nilai = 42;
    int *alamat = &nilai;
    printf("Nilai: %d\n", nilai);
    printf("Alamat: %p\n", (void *)alamat);
    printf("Dereference: %d\n", *alamat);
    return 0;
}
EOF
gcc -Wall -Wextra pointer.c -o pointer && ./pointer

int *alamat = &nilai menyimpan alamat nilai ke dalam pointer alamat. Operator * saat dipakai di depan pointer disebut dereference, yaitu membaca nilai yang ditunjuk. %p mencetak alamat dalam bentuk heksadesimal.

Pointer dan Fungsi

Pointer memungkinkan fungsi memodifikasi argumen asli, mengatasi keterbatasan passing by value dari episode 5:

Modifikasi lewat pointer
void tambah_satu(int *x) {
    (*x)++;
}
 
int main(void) {
    int angka = 10;
    tambah_satu(&angka);
    printf("%d\n", angka);
    return 0;
}

Fungsi tambah_satu(&angka) menerima alamat angka dan mengubah nilai aslinya lewat dereference. Tanpa pointer, perubahan hanya berlaku pada salinan di dalam fungsi.

Pointer terhadap Array, String, dan Fungsi

Nama Array adalah Pointer

Nama sebuah array bertindak sebagai pointer ke elemen pertamanya. Ini berarti nilai dan &nilai[0] menunjuk alamat yang sama. Aritmatika pointer memungkinkan iterasi elemen:

Iterasi array dengan pointer
int nilai[5] = {10, 20, 30, 40, 50};
for (int *p = nilai; p < nilai + 5; p++) {
    printf("%d ", *p);
}

Iterasi for (int *p = nilai; ...; p++) memajukan pointer satu elemen per langkah, bukan satu byte. Ukuran langkah ditentukan oleh tipe pointer, sehingga int maju 4 byte pada platform umum.

String dan Pointer Fungsi

String yang tak dapat diubah disimpan sebagai pointer ke char: const char *s = "teks". Pointer ke fungsi, seperti yang diperkenalkan di episode 5, menyimpan alamat fungsi sehingga fungsi bisa dipilih saat runtime. Keduanya menunjukkan bahwa pointer adalah konsep umum, bukan khusus data saja.

Dynamic Memory Allocation

malloc, calloc, realloc, dan free

Memori heap dialokasikan saat runtime melalui empat fungsi dari <stdlib.h>:

  • malloc: mengalokasikan byte tanpa menginisialisasi.
  • calloc: mengalokasikan dan mengisi nol.
  • realloc: mengubah ukuran blok yang sudah ada.
  • free: melepaskan blok kembali ke sistem.
Alokasi dinamis
cat > alokasi.c <<'EOF'
#include <stdio.h>
#include <stdlib.h>
 
int main(void) {
    int *data = malloc(5 * sizeof(int));
    if (data == NULL) {
        return 1;
    }
    for (int i = 0; i < 5; i++) {
        data[i] = i * i;
    }
    int *besar = realloc(data, 10 * sizeof(int));
    if (besar != NULL) {
        data = besar;
    }
    free(data);
    return 0;
}
EOF
gcc -Wall -Wextra alokasi.c -o alokasi && ./alokasi

Pola malloc(5 * sizeof(int)) mengalokasikan cukup memori untuk 5 int. Selalu periksa hasil NULL karena alokasi bisa gagal. realloc mengembalikan pointer baru yang mungkin berbeda, dan free harus dipanggil tepat sekali untuk setiap blok.

Mengukur Kebocoran dengan Valgrind

Kebocoran memori terjadi ketika blok dialokasikan tetapi tidak pernah di-free. Deteksi dengan valgrind:

Deteksi kebocoran memori
valgrind --leak-check=full ./alokasi

Output valgrind --leak-check=full ./alokasi melaporkan blok yang belum di-free. Kalimat "All heap blocks were freed" berarti tidak ada kebocoran — target yang harus selalu kalian kejar.

Pointer Safety dan Bug Umum

Null Pointer dan Use-After-Free

Dua bug memori paling umum adalah:

  • Null pointer dereference: memakai pointer bernilai NULL.
  • Use-after-free: memakai pointer setelah blok yang ditunjuk sudah di-free.
  • Double free: memanggil free dua kali pada pointer yang sama.

Semua bug di atas memicu perilaku tak terdefinisi yang bisa crash atau korupsi data. Disiplin pencegahan: selalu inisialisasi pointer, periksa NULL, set pointer ke NULL setelah free, dan gunakan satu pemilik untuk setiap blok memori.

Pola aman free
free(data);
data = NULL;

Urutan free(data); data = NULL; mencegah use-after-free dan double free karena pemakaian pointer NULL akan langsung ketahuan. Pola ini sederhana tetapi menyelamatkan produksi.

Warning

Perilaku yang didefinisikan oleh standar C hanyalah sebagian kecil dari yang terlihat masuk akal. Mendereference pointer yang salah, membaca di luar array, atau memakai blok yang sudah di-free semuanya adalah undefined behavior yang harus dihindari sejak awal.

Penutup

Inti yang harus dibawa pulang:

  • Pointer menyimpan alamat memori, bukan nilai; & mengambil alamat dan * mendereference.
  • Nama array bertindak sebagai pointer ke elemen pertama.
  • malloc, calloc, realloc, dan free mengelola memori heap secara manual.
  • Selalu periksa NULL hasil alokasi sebelum memakai.
  • Setiap blok malloc harus di-free tepat satu kali.
  • Deteksi kebocoran dengan valgrind dan hindari use-after-free.

Di episode 8 selanjutnya kita akan membahas input/output dan file handling — standard I/O dengan printf, scanf, getchar, dan putchar, file I/O dengan fopen, fread, fwrite, fprintf, fgets, dan fclose, file pointer dan mode file, hingga error handling I/O dengan errno dan perror.

Belajar C Language - Pointer & Memory Management | Belajar C Language