0x0 konumuna işaret eden bir işaretçi ile NULL olarak ayarlanmış bir işaretçi arasındaki fark nedir?


12

0x0000'ü gösteren bir işaretçi NULL olarak ayarlanmış bir işaretçi ile aynı mı? C dilinde NULL değeri tanımlanmışsa, fiziksel olarak hangi konuma çevrilir? 0x0000 ile aynı mı? Bu kavramlar hakkında daha fazla bilgiyi nerede bulabilirim?


1
Bu, Stack Overflow - stackoverflow.com/questions/1296843/… adresinde zaten sorulmuştur . Bence bu bizim için bir sınır, ama şu an için şüphenin faydasını vermeye hazırım.
ChrisF

Yanıtlar:


13

Buradaki cevapların çoğunun, en azından açıkça değil, ele almadığı bir nokta, boş gösterici yürütme sırasında var olan bir değerdir ve boş gösterici sabiti , C kaynak kodunda bulunan sözdizimsel bir yapıdır.

Bir boş gösterici sabit Karlson cevabı doğru ifade ettiği gibi, ya 0 değerine (basit bir sabit ifadesidir 0en yaygın örnek) ya da bu tür bir ekspresyon döküm void*(örneğin (void*)0).

NULL, <stddef.h>uygulama tarafından tanımlanan bir boş işaretçi sabitine genişleyen bir makro ve diğer birçok standart üstbilgidir . Genişletme tipik olarak ya 0da ((void*)0)(diğer dil kurallarını karşılamak için dış parantez gereklidir).

Dolayısıyla, bir değişmez 0, işaretçi türünün ifadesini gerektiren bir bağlamda kullanıldığında, her zaman bir null pointernesneye işaret etmeyen benzersiz bir işaretçi değeri olarak değerlendirilir . Yani yok değil bir temsili hakkında bir şey ima null işaretçi . Boş göstergeler çok sık olarak sıfır biti olarak temsil edilir, ancak herhangi bir şey olarak temsil edilebilirler. Ancak bir boş gösterici olarak temsil edilir olsa bile 0xDEADBEEF, 0ya da (void*)0yine bir olan boş işaretçisi sabiti .

Stackoverflow hakkındaki soruya verilen bu cevap bu konuyu çok iyi kapsamaktadır.

Bu, diğer şeylerin yanı sıra, memset()veya calloc()bir bellek bölgesini all-bit-sıfıra ayarlayabilen, o bölgedeki hiçbir işaretçiyi boş göstericilere ayarlamayacaktır. Çoğu uygulamada bunu yaparlar, ancak dil bunu garanti etmez.

Bu soru kopyası kabul edilmez neden bilmiyorum bu bir , ya da burada topikal var nasıl.


1
C'nin tasarımı ve evrimi ile ilgili peelinglerimden biri, sıfır basamağının boş göstericinin itiraz edilmemiş bir temsili olarak kullanılmaya devam etmesidir. Dilin ilk günlerinde (örneğin, işlev prototipleri gibi şeylerin ortaya çıkmasından önce), işaretçiler ve tamsayılar, boş bir işaretçi için "0" kullanmanın basit ve "sadece işe yarayacağı" kadar yeterince değiştirilebiliyordu. Bununla birlikte, sıfır tamsayısı ile bir boş gösterici arasında ayrım yapılması gerektiğinde, "0" gösterimi bir anahtar kelime ya da işleç dizisi lehine kullanımdan kaldırılmış olmalıdır.
supercat

Bu, NULL işaretçisinin platforma bağlı olarak NULL atandığında bir yere işaret edebileceği anlamına mı geliyor? Boş işaretçi sabiti sözdizimsel bir yapı olabilir, ancak kod çalıştırıldığında tam olarak ne olur? Bu sözdizimsel yapının GNU / Linux platformunda derlendiğini varsayalım. NULL değerini atadığımızda işaretçi değeri nedir? Bu adresin diğer adreslerden farkı nedir?
Arpith

1
@Arpith: Bir işaretçi nesnesine NULLherhangi bir boş işaretçi sabiti atama veya bu nesnenin değerini boş bir işaretleyiciye ayarlar . Makine düzeyinde, geçerli bir bellek belleğine işaret edebilir. Boş bir işaretçinin kaydı silindiğinde tanımlanmamış davranış var; adresten bir bellek yığınına erişmek 0x0000000, tam anlamıyla başka bir şey gibi geçerli bir davranıştır. Bu adres, diğer herhangi bir adresten farklıdır (a) eşittir NULLve (b) eşitsiz bir işaretçi ile bir C nesnesini karşılaştırarak. Boş gösterici, hiçbir şeye işaret etmediğini belirtmek için kullanılan rastgele bir işaretçi değeridir.
Keith Thompson

1
Makine düzeyinde, geçerli bir bellek yığınına işaret edebilir , ancak çoğu C ortamında geçersiz belleğe işaret eder, böylece işaretçiyi kullanmaya yönelik herhangi bir girişim bir donanım tuzağına / hatasına / istisnasına neden olur. Genellikle sadece en basit donanım platformlarında --- bellek yönetimi desteği olmayanlar - NULL işaretçisi geçerli bir bellek konumuna işaret eder.
Solomon Slow

7

Dışarıdaki her platform NULL'u istediği gibi tanımlamakta serbesttir.

C Standardına göre, bir işaretçiye sıfır atarsanız, bir NULL değerine dönüştürülür (bu platform için.) Ancak, bir NULL işaretçisi alıp int'e çevirirseniz, sıfır alacağınızın garantisi yoktur. her platformda. Ancak gerçek şu ki çoğu platformda sıfır olacak.

C Dil Şartnamesi'nde bulabileceğiniz şeyler hakkında bilgi . Güvenilirliğini garanti edemediğim bir kaynak şudur: http://www.winapi.co.kr/pds/doc/ISO-C-FDIS.1999-04.pdf


2
Standarttan kopmayı seçerse, yeniden tanımlamakta serbesttirler NULL pointer constant. Bildiğim kadarıyla orada bunu yapan hiçbir derleyici yoktur.
Karlson

0 olarak NULL uygulamayan herhangi bir derleyici var mı? Ve NULL değerinin yanlış olarak değerlendirileceği garanti ediliyor mu?
ugoren

NULL değeri standart tarafından false olarak değerlendirilir. NULL'ı 0 olarak uygulamayan herhangi bir derleyici (platform) var mı bilmiyorum ve ciddi olarak şüphe ediyorum, ancak standart bunu yasaklamıyor, kim bilir.
Mike Nakis

Platform makinesi dileği ve tanımındaki gibi olabilir, şu bellekte arka plan "boş gösterici sabit" temsili arasındaki karmaşa (spec belirtildiği gibi) bulunmaktadır NULLgenişletmek için olan makro 0C ++ ve her iki 0ya da (void *)0C, çünkü bu gerçek "boş işaretçi sabiti" dir.
Jan Hudec

NULL teoride herhangi bir şey olarak tanımlanabilse de, standart tarafından bir işaretçiye yazılan 0 değerine sahip bir int sabitinin bir boş gösterici ile sonuçlanacağına dair bir garanti vardır (ISO 9899: 1999 6.3.2.3/3). Stddef.h dosyasının NULL makrosu bir boş gösterici (7.17 / 3) olmalıdır, bu nedenle derleyicinin NULL'u 0 veya (void *) 0 olarak uygulamaması çok külfetli olacaktır.

1

C dilinde tanımlanmıştır, çünkü eşit olduğu tek bir makine adresi yoktur. Olsaydı, ondan bir soyutlamaya ihtiyacımız olmazdı! Çoğu platformda, NULL sonunda bir tür veya başka bir 0 olarak uygulanabilir, ancak taşınabilirliği önemsiyorsanız bunun evrensel olarak olduğunu varsaymak yanlıştır.



0

Göre Cı Standart Belge bölümünde 6.3.2.3:

0 değerine sahip bir tamsayı sabit ifadesine veya void * türüne atanan böyle bir ifadeye boş işaretçi sabiti denir.55) Boş bir işaretçi sabiti bir işaretçi türüne dönüştürülürse, sonuçtaki işaretçi boş işaretçi olarak adlandırılır. bir işaretçiye eşit olmayan herhangi bir nesne veya işlevin karşılaştırılması garanti edilir.

Şimdiye kadar bundan kopmuş bir derleyici görmedim.


@ PéterTörök Haklısın, bu bir yazım. :)
Karlson

1
Evet, ancak işaretçi hakkında aslında 0 değerine sahip bir şey söylemediğine dikkat edin. Çoğu platformda olsa da olmayabilir.
Jan Hudec
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.