C ve C++'ta segmentation fault: nedenleri ve AddressSanitizer ile bulmak
"Segmentation fault (core dumped)" mesajı, programın erişim izni olmayan bir bellek bölgesine dokunduğu anlamına gelir. Hata mesajı nerede olduğunu söylemediği için yeni başlayanları en çok uğraştıran sorunlardan biridir.
En sık nedenler
- NULL ya da başlatılmamış işaretçi:
int *p; *p = 5;gibi bir atama rastgele bir adrese yazmaya çalışır. - Dizi sınırlarının dışına çıkmak: 10 elemanlı dizinin 10. indeksine erişmek (indeksler 0–9'dur).
- Serbest bırakılmış belleği kullanmak (use-after-free):
free(p)ya dadelete psonrasıp'ye erişmek. - Yığın taşması: Sonsuz özyineleme ya da yığında çok büyük dizi tanımlamak.
- scanf'te & unutmak:
scanf("%d", x);yerinescanf("%d", &x);yazılmalı. - Fonksiyondan yerel değişkenin adresini döndürmek: Fonksiyon bittiğinde o bellek geçersizdir.
AddressSanitizer ile yerini bulmak
GCC ve Clang'de gelen AddressSanitizer (ASan), hatayı tam satırıyla gösterir:
gcc -g -fsanitize=address -fno-omit-frame-pointer program.c -o program
./program
Hata olduğunda hangi dosyanın hangi satırında, ne tür bir erişim yapıldığını ve belleğin nerede ayrılıp nerede serbest bırakıldığını raporlar. C++ için g++ ile aynı bayraklar geçerlidir. Visual Studio'nun güncel sürümlerinde de /fsanitize=address desteği vardır.
GDB ile çökme anını incelemek
gcc -g program.c -o program
gdb ./program
(gdb) run
(gdb) bt
bt (backtrace) çökme anındaki çağrı zincirini gösterir. print degisken ile değerlere bakabilirsin.
Valgrind
Linux'ta valgrind ./program da bellek hatalarını ve sızıntılarını bulur. ASan'a göre yavaştır ama yeniden derleme gerektirmez (yine de -g ile derlemek satır bilgisini verir).
Önleyici alışkanlıklar
- Derlerken uyarıları aç:
-Wall -Wextra. Pek çok hata daha derlerken yakalanır. - İşaretçileri tanımlarken
NULL(C++'tanullptr) ile başlat,freesonrası tekrarNULLyap. - C++'ta ham
new/deleteyerinestd::vector,std::string,std::unique_ptrkullan; bellek yönetimini kütüphaneye bırak.
Çöken bir kodun varsa, en küçük tekrar üretilebilir parçasını ve ASan çıktısını bu konuya ekleyerek sorabilirsin.