0Pricing
C Academy · Pelajaran

Akses Tidak Valid

Di luar batas dan belum diinisialisasi.

Akses Tidak Valid adalah pelajaran C Academy gratis di CoddyKit. Ini adalah pelajaran 3 dari 4. Kamu bisa membaca pelajaran lengkapnya di bawah secara gratis — lalu praktikkan langsung di browser dengan editor kode bawaan dan tutor AI 24/7. Ini adalah bagian dari jalur belajar C Academy, dan progresmu tersinkronisasi di web dan aplikasi CoddyKit. Kursus C Academy mencakup 4 pelajaran total.

Di Luar Kebocoran

Kebocoran membuang-buang memori, tetapi bug akses yang tidak valid merusaknya. memcheck menangkap beberapa jenis bug:

  • Membaca atau menulis melewati akhir buffer
  • Menggunakan memori setelah free
  • Membaca nilai yang belum diinisialisasi
  • Membaca atau menulis melalui pointer yang salah

Bug-bug ini menyebabkan kerusakan yang paling berbahaya dan paling sulit direproduksi.

Penulisan di Luar Batas

Program ini mengalokasikan ruang untuk 5 int, tetapi menulis ke indeks 5, yaitu slot keenam.

Indeks 5 berada satu elemen setelah akhir. memcheck melaporkan Invalid write of size 4 pada baris ini.

#include <stdlib.h>

int main(void) {
    int *a = malloc(5 * sizeof(int));
    a[5] = 99; /* valid indices are 0..4 */
    free(a);
    return 0;
}

Membaca Kesalahan

Laporan tersebut menyebutkan operasi, ukuran, dan hubungan akses dengan blok:

Invalid write of size 4
Address 0x... is 0 bytes after a block of size 20 alloc'd

Pesan '0 bytes after a block of size 20' memberi tahu bahwa akses terjadi tepat setelah alokasi berukuran 20 byte (5 int).

Pembacaan di Luar Batas

Pembacaan juga terdeteksi. Di sini, loop berjalan satu elemen terlalu jauh.

memcheck menandai Invalid read of size 4 pada iterasi terakhir, meskipun program mungkin tampak 'berjalan' karena kebetulan.

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

int main(void) {
    int *a = calloc(3, sizeof(int));
    for (int i = 0; i <= 3; i++)   /* should be i < 3 */
        printf("%d\n", a[i]);
    free(a);
    return 0;
}

Nilai yang Belum Diinisialisasi

malloc tidak mengosongkan memori. Menggunakannya sebelum menetapkan nilai akan menghasilkan nilai yang tidak dapat diprediksi.

memcheck melaporkan Conditional jump or move depends on uninitialised value(s) ketika nilai seperti itu memengaruhi alur kontrol atau keluaran.

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

int main(void) {
    int *p = malloc(sizeof(int));
    if (*p == 0)              /* *p was never set */
        printf("zero\n");
    free(p);
    return 0;
}

Mengapa Laporan Nilai yang Belum Diinisialisasi Terlambat

memcheck tidak mengeluh tepat saat Anda membaca memori yang belum diinisialisasi. memcheck melacak status 'definedness' dan hanya melaporkannya ketika nilai yang belum didefinisikan benar-benar berpengaruh, misalnya pada percabangan, keluaran, atau pemanggilan sistem.

Dengan begitu, peringatan palsu saat Anda menyalin byte yang belum diinisialisasi tanpa dampak dapat dihindari.

Penggunaan Setelah Dibebaskan

Menyentuh memori setelah membebaskannya adalah perilaku yang tidak terdefinisi. memcheck mendeteksinya dengan tepat.

memcheck melaporkan Invalid read of size 4 dengan catatan Address ... is 0 bytes inside a block of size 4 free'd, dan bahkan menunjukkan lokasi terjadinya free.

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

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

Pembebasan Ganda

Membebaskan pointer yang sama dua kali akan merusak pencatatan internal pengalokasi.

memcheck melaporkan Invalid free() dan menampilkan pembebasan saat ini serta alokasi awalnya, sehingga kesalahannya terlihat jelas.

#include <stdlib.h>

int main(void) {
    int *p = malloc(sizeof(int));
    free(p);
    free(p);   /* freed twice */
    return 0;
}

Melacak Asal

Untuk kesalahan nilai yang belum diinisialisasi, tambahkan --track-origins=yes.

memcheck kemudian melaporkan di mana nilai yang bermasalah dibuat, bukan hanya di mana nilai itu digunakan, sehingga peringatan yang samar berubah menjadi perbaikan yang tepat.

valgrind --track-origins=yes ./prog

Tumpukan dan Variabel Global

memcheck sangat baik dalam menangani kesalahan heap. Untuk luapan pada tumpukan atau di dalam larik global, cakupannya lebih lemah.

Dalam kasus tersebut, AddressSanitizer (gcc -fsanitize=address) sering kali menjadi pilihan yang lebih baik. Kedua alat ini saling melengkapi.

Selisih Satu: Terminator Null

Luapan heap yang sering terjadi adalah lupa menambahkan terminator string. strlen mengembalikan 5 untuk 'hello', tetapi string tersebut memerlukan 6 byte untuk menyimpan '\0' di bagian akhir.

memcheck melaporkan Invalid write ketika strcpy menulis byte terakhir itu melewati batas akhir.

#include <stdlib.h>
#include <string.h>

int main(void) {
    char *s = malloc(strlen("hello")); /* needs +1 */
    strcpy(s, "hello");                 /* writes the '\0' past end */
    free(s);
    return 0;
}

Pemeriksaan Cepat

Identifikasi apa yang dilaporkan memcheck untuk cuplikan tersebut.

Ringkasan

Sekarang Anda dapat mengenali bug akses yang tidak valid:

  • Pembacaan/penulisan di luar batas ditampilkan sebagai Invalid read/write beserta offset bloknya
  • Nilai yang belum diinisialisasi ditandai ketika memengaruhi keputusan atau keluaran
  • Penggunaan setelah pembebasan dan pembebasan ganda terdeteksi beserta kedua lokasi pemanggilannya
  • --track-origins=yes menunjukkan lokasi nilai yang tidak terdefinisi; padukan dengan ASan untuk bug pada tumpukan

Berikutnya: membaca laporan lengkap.

Pertanyaan yang Sering Diajukan

Apakah pelajaran “Akses Tidak Valid” gratis?

Ya — teks lengkap “Akses Tidak Valid” gratis dibaca di sini di web. Untuk praktiknya secara interaktif (editor kode bawaan dan tutor AI 24/7) dan buka sisa kursus C Academy, upgrade ke CoddyKit PRO. Kursus C Academy mencakup 4 pelajaran total.

Apa yang akan aku pelajari di “Akses Tidak Valid”?

Di luar batas dan belum diinisialisasi. Kamu berlatih C Academy dengan kode praktik yang langsung kamu jalankan di browser, dan tutor AI 24/7 menjawab pertanyaanmu saat kamu mengerjakan pelajaran ini.

Apakah aku perlu pengalaman untuk memulai C Academy?

Tidak diperlukan pengalaman sebelumnya. C Academy di CoddyKit dirancang untuk pemula hingga pelajar tingkat lanjut, jadi kamu bisa memulai di sini atau dari awal dan belajar sesuai kecepatan kamu sendiri. Ini adalah pelajaran 3 dari 4.

Berapa lama pelajaran “Akses Tidak Valid” memakan waktu?

Sebagian besar pelajaran CoddyKit memakan waktu sekitar 5–10 menit. Setiap pelajaran ringkas dan interaktif, jadi kamu membuat kemajuan stabil dan melanjutkan dari tempat kamu tinggalkan di web dan aplikasi.

Bisakah aku menulis dan menjalankan kode dalam pelajaran C Academy ini?

Ya. Setiap pelajaran C Academy menyertakan editor kode bawaan, jadi kamu menulis dan menjalankan kode nyata langsung di browser dan mendapatkan umpan balik AI instan — tidak diperlukan penyiapan lokal.

Semua pelajaran dalam kursus ini

  1. Mengapa Valgrind
  2. Mendeteksi Kebocoran
  3. Akses Tidak Valid
  4. Membaca Laporan
← Kembali ke C Academy