Segmentation Fault (Segfault) Nedir?
Segmentation fault (segfault), bir program erişim izni olmayan bir belleği okumaya ya da yazmaya çalıştığında, örneğin bir null işaretçi üzerinden 0 adresine eriştiğinde ortaya çıkan bir çökmedir. İşletim sistemi programı SIGSEGV sinyaliyle durdurur.
Güncellendi: 24 Eylül 2026
Bir C programı ilk satırını yazdırır, sonra kimsenin yazmadığı bir mesajla durur:
#include <stdio.h>
int main(void) {
int *score = NULL;
printf("About to read the score\n");
printf("Score: %d\n", *score);
return 0;
}
About to read the score
bash: line 1: 64030 Segmentation fault: 11 ./seg
Bu çıktı macOS'taki bash'ten; 64030 süreç kimliği (PID), 11 de sinyal numarası. Linux'ta aynı çökme genellikle Segmentation fault (core dumped) şeklinde görünür. Her iki durumda da program notu hiç yazdırmadı. score 0 adresini tutuyor ve *score işlemciden o adresteki belleği okumasını istiyor; buna hiçbir programın izni yoktur.
Segmentation fault nasıl oluşur
Her program kendi sanal adres alanında çalışır: işletim sisteminin parça parça doldurduğu devasa bir adres aralığı. İşletim sistemi programın kodunu, global değişkenlerini, yığınını (stack) ve heap'ini bu aralığa sayfa (page) denen bloklar halinde eşler (çoğu x86 Linux sisteminde 4 KB, Apple silicon'lu Mac'lerde 16 KB). Adreslerin çoğu eşlenmeden bırakılır ve null işaretçi hataları yakalansın diye 0 adresi her zaman bunların arasındadır.
- Program bir adresi okuyan ya da yazan bir komut çalıştırır. Burada bu, 0 adresindeki
*scoreokumasıdır. - İşlemcinin bellek yönetim birimi (MMU) adresi sayfa tablosunda arar. Sayfa eşlenmemiştir ya da program salt okunur bir sayfaya yazmaya çalışmaktadır.
- İşlemci komutu durdurur ve bir sayfa hatası (page fault) ile kontrolü çekirdeğe (kernel) verir.
- Çekirdek erişimin yasal olup olamayacağını kontrol eder, örneğin büyümesi gereken bir yığın. Değildir, bu yüzden çekirdek sürece 11 numaralı sinyali,
SIGSEGV'yi gönderir. SIGSEGViçin varsayılan eylem süreci sonlandırmak ve sistem izin veriyorsa bir core dump kaydetmektir. Ardından kabuk mesajı yazdırır ve çıkış durumunu 139'a, yani 128 artı sinyal numarasına ayarlar.
Yani segmentation fault derleyici tarafından bildirilmez ve dilin fırlattığı bir istisna da değildir. Belleği koruyan donanım ve çekirdektir; bu da onu en ani türden bir çalışma zamanı hatası yapar. Windows aynı olayı access violation olarak, 0xC0000005 istisna koduyla ele alır.
Segmentation fault'un yaygın nedenleri
C ve C++ bir programın herhangi bir adresi hesaplayıp kullanmasına izin verir; bu yüzden nedenler geçerli olmayan bir adresi kullanmaya indirgenir.
- Bir null işaretçinin gösterdiği değere erişmek (dereference).
int *p = NULL; *p = 5;mallocya dafopengibi başarısız olduğundaNULLdöndüren bir fonksiyon, sonucu kontrol edilmezse buraya götürür. - Bir dizinin sonunun çok ötesinde bir indeks. C sınırları kontrol etmez;
arr[1000000]sadece bir milyon eleman ilerideki bir adrestir. freesonrasında belleği kullanmak. İşaretçi hâlâ eski adresi tutar ama bellek artık sana ait değildir.- İlk değer verilmemiş bir işaretçi.
int *p; *p = 5;p'nin o anda tuttuğu rastgele değer üzerinden yazar. - Yığın taşması (stack overflow). Durma koşulu olmayan özyinelemeli bir fonksiyon, yığının sonunu aşana kadar yığın çerçevesi eklemeye devam eder. Aşağıdaki örnek macOS'ta
Segmentation fault: 11ve 139 çıkış durumuyla çöktü. - Bir string literal'e yazmak.
char *name = "coddy"; name[0] = 'C';salt okunur belleği değiştirmeye çalışır. Linux'ta bu bir segfault'tur. macOS'ta aynı program ilgili bir sinyal olanBus error: 10ile durdu.
#include <stdio.h>
int depth(int n) {
return depth(n + 1) + 1; /* never stops calling itself */
}
int main(void) {
printf("%d\n", depth(0));
return 0;
}
Küçük bir hata çoğu zaman hiç çökmeye yol açmaz, bu da onu daha tehlikeli yapar. Bu döngü üç elemanlı bir dizinin sonundan bir eleman fazlasını okur:
#include <stdio.h>
int main(void) {
int scores[3] = {72, 88, 95};
int total = 0;
for (int i = 0; i <= 3; i++) { /* <= reads scores[3] */
total += scores[i];
}
printf("Total: %d\n", total);
return 0;
}
Bir Mac'te Clang ile derlendiğinde Total: 256 yazdırdı. Doğru toplam 255. scores[3] yığının sonraki 4 byte'ıydı ve programa aitti; bu yüzden hata oluşmadı ve rastgele değer sessizce toplandı. İşletim sistemi yalnızca programın hiç sahip olmadığı belleğe erişimleri durdurur.
İki hatanın çözümü de aynı alışkanlıktır: kaç eleman olduğunu bil ve bir işaretçiyi izlemeden önce kontrol et.
Best: 95
No scores, nothing to read
"Core dumped" ne demek
Core dump, programın çöktüğü andaki belleğinin bir kopyasını tutan bir dosyadır. Bir debugger onu daha sonra açıp programın tam olarak nerede olduğunu ve değişkenlerinin ne tuttuğunu gösterebilir: gdb ./app core. Birçok Linux dağıtımında bu dosyaları systemd-coredump toplar ve coredumpctl list onları gösterir. Core dump'lar kapalıyken, örneğin ulimit -c 0 ile, mesaj parantez içindeki kelimeler olmadan sadece Segmentation fault olur.
Çöken satır nasıl bulunur
Programın çöktüğü satır çoğu zaman hatanın olduğu satır değildir. Bir işaretçi bir fonksiyonda geçersiz hale gelip çok daha sonra başka bir fonksiyonda kullanılabilir. Bu araçlar ikisini de gösterir.
Debugger. Hata ayıklama bilgisiyle derle ve programı debugger içinde çalıştır. Program durduğunda bt (backtrace) fonksiyon çağrı zincirini dosya adları ve satır numaralarıyla yazdırır. Linux'ta debugger genellikle gdb, macOS'ta ise lldb'dir; orada da bt aynı şekilde çalışır.
gcc -g app.c -o app
gdb ./app
(gdb) run
(gdb) bt
AddressSanitizer. -fsanitize=address ile derle (GCC ve Clang ikisi de destekler) ve programı normal şekilde çalıştır. Çıplak bir segfault yerine, heap-use-after-free ya da stack-buffer-overflow gibi hatanın türünü adlandıran, erişimi yapan satırı ve belleği ayıran satırı gösteren bir rapor yazdırır. Yukarıdaki, kendi başına hiç çökmeyen sessiz sonun bir ötesini okuma hatasını da yakalar.
Valgrind. Linux'ta valgrind ./app değiştirilmemiş bir programı çalıştırır ve Invalid read of size 4 gibi her geçersiz okuma ya da yazmayı bildirir.
Diğer dillerde segmentation fault
Python, Java ve JavaScript her indeksi ve her referansı kullanmadan önce kontrol eder; bu yüzden aynı hatalar açık mesajlı istisnalara dönüşür: Python'da IndexError ya da AttributeError, Java'da ArrayIndexOutOfBoundsException ya da NullPointerException, JavaScript'te TypeError. Bunlar istisna yönetimi ile yakalanabilir. Bir segfault bu şekilde ele alınamaz: bir sinyaldir ve bir C++ catch bloğu onu görmez.
Python programları, altlarındaki C kodu başarısız olduğunda yine de segfault verebilir. Bu satır ctypes'tan 0 adresini okumasını ister:
import ctypes
ctypes.string_at(0)
python3 -X faulthandler ile çalıştırıldığında Python 3.12, Fatal Python error: Segmentation fault ve ardından çalışmakta olan Python satırlarını yazdırdı. Bir C eklentisinde ya da native bir kütüphanede bellek hatası olduğunda da aynı çökme olur. Rust farklı bir yaklaşım izler: derleyicisi geçersiz belleğe erişebilecek kodun çoğunu program derlenmeden reddeder.
Sırada ne var
C'deki segmentation fault rehberi her nedeni minimal bir program ve çözümüyle adım adım anlatır. Bu hataları en baştan önlemek için işaretçiler, null işaretçiler ve stack ile heap hakkında oku, sonra bunları C kursunda pratik et. Belleği senin yerine kontrol eden dillerde hataların nasıl bildirildiğini görmek için çalışma zamanı hatası sayfasına bak.
Sıkça Sorulan Sorular
Segmentation fault nasıl düzeltilir?
-g ile derle ve programı gdb ya da lldb altında çalıştır, çökmeden sonra bt yaz; ya da ayrıntılı bir rapor için -fsanitize=address ile derle. Sonra o satırın kullandığı işaretçiyi ya da indeksi düzelt: işaretçileri NULL için kontrol et, dizi indekslerini uzunluğun altında tut, free sonrasında belleği kullanma ve özyinelemenin bittiğinden emin ol.Segmentation fault bir bellek sızıntısı mıdır?
free hataları segfault'a, free'yi unutmak ise sızıntıya yol açar.Neden segmentation fault deniyor?
SIGSEGV sinyal adı kaldı. Windows aynı olaya access violation (erişim ihlali) der.Python'da segmentation fault olur mu?
ctypes. python -X faulthandler script.py çalıştırmak, çöktüğü anda çalışan Python satırlarını yazdırır.Exit code 139 ne demek?
SIGSEGV (segmentation fault) ile sonlandırıldığı anlamına gelir. Kabuklar sinyalle ölen bir süreci 128 artı sinyal numarası olarak bildirir: 128 + 11 = 139. Docker ve Kubernetes'te 139 ile çıkan bir konteynerin ana süreci segfault vermiştir.