Akses Tidak Sah
Di luar batas dan belum dimulakan
Akses Tidak Sah ialah pelajaran C Academy percuma di CoddyKit. Ini ialah pelajaran 3 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.
Melangkaui Kebocoran
Kebocoran membazirkan memori, tetapi pepijat capaian tidak sah merosakkannya. memcheck menangkap beberapa jenis:
- Membaca atau menulis melepasi hujung penimbal
- Menggunakan memori selepas
free - Membaca nilai yang belum dimulakan
- Membaca atau menulis melalui penuding yang salah
Ini menyebabkan ranap yang paling berbahaya dan paling sukar dihasilkan semula.
Penulisan Di Luar Sempadan
Ini memperuntukkan ruang untuk 5 int tetapi menulis pada indeks 5, iaitu slot keenam.
Indeks 5 ialah satu elemen selepas hujung. 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 Ralat
Laporan itu menamakan operasi, saiz dan hubungannya dengan blok:
Invalid write of size 4Address 0x... is 0 bytes after a block of size 20 alloc'd
“0 bytes after a block of size 20” memberitahu anda bahawa capaian berlaku tepat selepas peruntukan 20 bait (5 int).
Bacaan Di Luar Sempadan
Bacaan juga dikesan. Di sini gelung berjalan satu elemen terlalu jauh.
memcheck menandakan Invalid read of size 4 pada lelaran terakhir, walaupun program mungkin “berfungsi” secara 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 Dimulakan
malloc tidak menetapkan memori kepada sifar. Menggunakannya sebelum memberikan nilai menghasilkan nilai yang tidak dapat diramalkan.
memcheck melaporkan Conditional jump or move depends on uninitialised value(s) apabila nilai sedemikian mempengaruhi aliran kawalan atau output.
#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 Belum Dimulakan Tertangguh
memcheck tidak mengadu sebaik sahaja anda membaca memori yang belum dimulakan. Ia menjejaki “takrifan” dan hanya melaporkan apabila nilai tidak ditakrifkan itu benar-benar penting, seperti dalam cabang, output atau panggilan sistem.
Ini mengelakkan amaran palsu apabila anda menyalin bait yang belum dimulakan secara tidak berbahaya.
Penggunaan Selepas Pembebasan
Menyentuh memori selepas membebaskannya ialah tingkah laku tidak ditakrifkan. memcheck mengesannya dengan tepat.
Ia melaporkan Invalid read of size 4 dengan nota Address ... is 0 bytes inside a block of size 4 free'd, malah menunjukkan tempat free berlaku.
#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 Berganda
Membebaskan penuding yang sama dua kali merosakkan rekod perakaunan pengagih memori.
memcheck melaporkan Invalid free() dan menunjukkan pembebasan semasa serta peruntukan asal, menjadikan kesilapan itu jelas.
#include <stdlib.h>
int main(void) {
int *p = malloc(sizeof(int));
free(p);
free(p); /* freed twice */
return 0;
}Jejak Asal
Untuk ralat nilai yang tidak dimulakan, tambahkan --track-origins=yes.
memcheck kemudian melaporkan tempat nilai yang salah itu created, bukan sekadar tempat nilai itu digunakan, lalu menukarkan amaran yang kabur kepada pembaikan yang tepat.
valgrind --track-origins=yes ./progTimbunan dan Pemboleh Ubah Global
memcheck sangat baik untuk mengesan ralat HEAP. Untuk limpahan pada stack atau dalam global arrays, liputannya lebih lemah.
Dalam keadaan itu, AddressSanitizer (gcc -fsanitize=address) biasanya pilihan yang lebih baik. Kedua-dua alat ini saling melengkapi.
Terlebih atau Terkurang Satu: Penamat Null
Limpahan HEAP yang kerap berlaku ialah terlupa menambah penamat rentetan. strlen mengembalikan 5 untuk 'hello', tetapi rentetan itu memerlukan 6 bait untuk menyimpan '\0' pada penghujungnya.
memcheck melaporkan penulisan tidak sah apabila strcpy menulis bait terakhir itu selepas penghujung.
#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;
}Semakan Pantas
Kenal pasti perkara yang dilaporkan oleh memcheck untuk coretan kod tersebut.
Ringkasan
Kini Anda boleh mengesan pepijat capaian yang tidak sah:
- Bacaan/tulisan di luar sempadan muncul sebagai bacaan/tulisan tidak sah berserta ofset blok
- Nilai yang tidak dimulakan ditandai apabila nilai itu mempengaruhi keputusan atau keluaran
- Penggunaan selepas pembebasan dan pembebasan berganda dikesan bersama kedua-dua lokasi panggilan
- Gunakan
--track-origins=yesuntuk menentukan lokasi nilai yang tidak ditakrifkan; padankan dengan ASan untuk pepijat pada stack
Seterusnya: membaca laporan penuh.
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 “Akses Tidak Sah” percuma?
Ya — teks penuh “Akses Tidak Sah” 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 “Akses Tidak Sah”?
Di luar batas dan belum dimulakan 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 3 daripada 4.
Berapa lamakah pelajaran “Akses Tidak Sah” 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
- Mengapa Valgrind
- Mengesan Kebocoran
- Akses Tidak Sah
- Membaca Laporan