Menu
Coddy logo textTech

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.

Yazan Kevin Spektor, Kurucu ortak ve CTO

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.

  1. Program bir adresi okuyan ya da yazan bir komut çalıştırır. Burada bu, 0 adresindeki *score okumasıdır.
  2. İş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.
  3. İşlemci komutu durdurur ve bir sayfa hatası (page fault) ile kontrolü çekirdeğe (kernel) verir.
  4. Ç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.
  5. SIGSEGV iç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; malloc ya da fopen gibi başarısız olduğunda NULL dö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.
  • free sonrası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: 11 ve 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 olan Bus error: 10 ile 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?
Önce satırı bul: -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?
Hayır, bunlar zıt sorunlardır. Bellek sızıntısı, programın ayırdığı ama hiç serbest bırakmadığı bellektir; program giderek daha fazla bellek kullanarak çalışmaya devam eder. Segmentation fault ise programın sahip olmadığı belleğe bir erişimdir ve program anında durdurulur. Bir işaretçiyi serbest bıraktıktan sonra kullanmak gibi free hataları segfault'a, free'yi unutmak ise sızıntıya yol açar.
Neden segmentation fault deniyor?
Ad, bellek segmentasyonundan gelir: bir programın belleğinin sabit sınırlı segmentlere bölündüğü eski bir tasarım. Kendi segmentinin dışındaki bir adrese dokunmak bir hataydı (fault). Modern sistemler belleği bunun yerine sayfalarla yönetir ama ad ve SIGSEGV sinyal adı kaldı. Windows aynı olaya access violation (erişim ihlali) der.
Python'da segmentation fault olur mu?
Sıradan Python kodu buna yol açmaz, çünkü Python her indeksi ve referansı kontrol eder ve bunun yerine bir istisna fırlatır. Yine de bir Python programı C kodu içinde segfault verebilir: bir C eklenti modülü, bir makine öğrenmesi framework'ü gibi bir kütüphane ya da 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?
Exit code 139, sürecin 11 numaralı sinyal, yani 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.
Coddy programming languages illustration

Coddy ile kodlamayı öğren

BAŞLA