SENARYO 1
int *nums = {5, 2, 1, 4};
printf("%d\n", nums[0]);
Bu neden segfault yapıyor?
numsİnt için bir gösterici olarak ilan ettiniz - bu, bellekte bir tamsayının numsadresini tutması gerekiyor .
Daha sonra birden çok değerden numsoluşan bir diziyi başlatmaya çalıştınız . Bu nedenle, çok fazla ayrıntıya girmeden, bu kavramsal olarak yanlıştır - tek bir değeri tutması gereken bir değişkene birden fazla değer atamak mantıklı değildir. Bu bağlamda, bunu yaparsanız tam olarak aynı etkiyi görürsünüz:
int nums = {5, 2, 1, 4};
printf("%d\n", nums);
Her iki durumda da (bir işaretçiye veya bir int değişkenine birden çok değer atayın), o zaman değişkenin ilk değeri alması, 5kalan değerler göz ardı edilir. Bu kod uyumludur ancak atamada olmaması gereken her ek değer için uyarılar alırsınız:
warning: excess elements in scalar initializer.
İşaret değişkenine birden çok değer atanması durumunda, program eriştiğinizde hata verir nums[0], bu da adres 5'te depolanan her şeyi harfi harfine ertelediğiniz anlamına gelir . numsBu durumda işaretçi için geçerli bir bellek ayırmadınız .
İnt değişkenine birden çok değer atama durumunda herhangi bir segfault olmadığını belirtmekte fayda var (burada herhangi bir geçersiz göstericiye başvuruda bulunmuyorsunuz).
SENARYO 2
int nums[] = {5, 2, 1, 4};
Bu, segfault değildir, çünkü yığında yasal olarak 4 inçlik bir dizi tahsis ediyorsunuz.
SENARYO 3
int *nums = {5, 2, 1, 4};
printf("%d\n", nums);
Bu, beklendiği gibi segfault vermez, çünkü siz işaretçinin değerini yazdırıyorsunuz - başvurunun iptalini DEĞİL (bu geçersiz bellek erişimidir).
Diğerleri
Bir işaretçinin değerini bu şekilde kodladığınızda neredeyse her zaman segfault'a mahkumdur (çünkü hangi işlemin hangi bellek konumuna erişebileceğini belirlemek işletim sisteminin görevidir).
int *nums = 5;
Dolayısıyla, temel bir kural, her zaman bazı tahsis edilmiş değişkenlerin adresine bir gösterici başlatmaktır , örneğin:
int a;
int *nums = &a;
veya,
int a[] = {5, 2, 1, 4};
int *nums = a;