Sıfır uzunluktaki diziye bir işaretçinin özellikleri


21

Düşünmek

int main()
{
    auto a = new int[0];
    delete[] a; // So there's no memory leak
}

Kopya başlatma ve silme arasında, işaretçiyi adresinde okuyabilir misiniz a + 1?

Ayrıca, dil derleyicinin ayarlanmasına izin averiyor nullptrmu?


2
@Fareanor: Kesinlikle okuyabilirsin a(kesinlikle dereference olamaz).
Bathsheba

8
@RasmiRanjanNayak: Bu hogwash.
Bathsheba

2
@RasmiRanjanNayak Oh my ... no
Ted Lyngmo

1
@TedLyngmo: "İşaretçiyi şurada oku" dediğimde a + 1, aşağıdaki kod auto b = a + 1;tanımsız davranış mı? (Sanirim oyle).
Bathsheba

2
@Ayxan 0aslında çalışma zamanına kadar bilmeyeceğiniz bir ifadenin sonucu olduğu durumda tahmin ediyorum . Yana new int[0]güvenlidir, bu bazı dallanma / özel durumlarda endişesi kurtarabilir. Bir std::vectorile başlatacak mıyım hayal edin std::vector<int> v(0);.
scohe001

Yanıtlar:


3
    auto a = new int[0];

Göre [basic.compound.3] , depolanan değeri aaşağıdakilerden biri olmalıdır:

  1. Bir nesneye işaretçi (türünde int)
  2. Bir nesnenin sonunu geçen bir işaretçi
  3. Boş
  4. Geçersiz

Yapılmış tipte bir nesne olmadığı için ilk olasılığı göz ardı edebiliriz int. Üçüncü olasılık, C ++ 'nın null olmayan bir işaretçi döndürülmesini gerektirdiği için reddedilir (bkz. [Basic.stc.dynamic.allocation.2] ). Böylece iki olasılık kalmıştır: bir nesnenin sonunu geçen bir işaretçi veya geçersiz bir işaretçi.

aSon bir işaretçi olarak görmeye meyilli olurum, ancak bunu kesin olarak belirlemek için saygın bir referansım yok. (Bununla birlikte, [basic.stc] 'de , deletebu işaretçiyi nasıl yapabileceğinizi gösteren güçlü bir ima vardır .) Bu yüzden bu cevapta her iki olasılığı da eğlendireceğim.

Kopya başlatma ve silme arasında, işaretçiyi adresinde okuyabilir misiniz a + 1?

Yukarıdakilerden hangisinin geçerli olduğuna bakılmaksızın, [expr.add.4] tarafından dikte edildiği gibi, davranış tanımsızdır .

Eğer abir son-uç işareti, o zaman indeksinde varsayımsal elemanına noktasına kabul edilir 0bir öğeye sahip olan bir dizi. Tamsayıyı ekleme jiçin asadece tanımlanan 0≤0+j≤nburada, ndizi boyutudur. Bizim durumumuzda, nsıfırdır, yani toplamı a+jyalnızca tanımlanır jolduğunu 0. Özellikle, ekleme 1tanımsızdır.

Eğer ageçersiz, o zaman girer temiz bir şekilde "Aksi takdirde, davranış tanımlanmamış." (Beklenmedik bir şekilde, tanımlanan durumlar yalnızca geçerli işaretçi değerlerini kapsar.)

Ayrıca, dil derleyicinin ayarlanmasına izin averiyor nullptrmu?

Hayır. Yukarıda belirtilen [basic.stc.dynamic.allocation.2] : "İstek başarılı olursa, değiştirilebilir bir ayırma işlevi tarafından döndürülen değer null olmayan bir işaretçi değeridir" . Ayrıca, C ++ 'ın (ancak C değil) sıfır talebine yanıt olarak null olmayan bir işaretçi gerektirdiğini söyleyen bir dipnot da vardır .


1
Geçersiz bir işaretçi değeri olsaydı
TC

@TC Doğru, bu geçersiz bir işaretçi değeri olamayacağı anlamına gelir.
Jamit

23

Sonucunda son CWG reflektör tartışma Başına editoryal sayısında 3178 , new int[0]henüz ne denir üretir "geçmiş-end" işaretçi değeri .

Bundan asonra null olamaz ve [expr.add] / 4a + 1 tarafından tanımlanmamıştır .


4
"3178 başyazı sorunu nedeniyle son CWG reflektör tartışması new int[0], şu anda" son "işaretçi değeri" denilen şeyi üretir Bu doğru değil. Çok fazla tartışma yoktu. Bir kişi, değerin "bir nesnenin sonunu geçmesi için işaretçi" olması gerektiğini öne sürdü ve bu ifade sorgulandı, çünkü 0öğeleri içeren bir dizi olması durumunda, sonuna kadar geçecek hiçbir nesne yok.
Language Lawyer

@LanguageLawyer a + 1, hiç bir durumda tanımsız olduğuna şüphe yok gibi görünüyor , bu yüzden amacınız sadece aboş olup olamayacağınızla mı ilgili ?
MM

Amaçlanan semantik hakkında herhangi bir anlaşmazlık olduğu veya bu işaretçi değerleri kategorisi için geçerli adın bu senaryo için uygun olmadığı anlaşılmadı.
TC

@MM Bence bu a + 1undefined ve belki de sonuçtaki işaretçi değeri "sonunu işaretçi" olarak adlandırılacaktır. Cevabın yanlış olduğunu söylemiyorum. Biraz doğru değildir, çünkü sonucun "sonun ötesinde işaretçi" olduğunu belirten bir uzlaşı ile uzun bir tartışma olduğu anlaşılabilir çünkü bu sorunu çözmek için yeterlidir. "Sonu geçen imleç" ile ilgili sorun, bir nesnenin sonunu geçmesi ve 1böyle bir imleç değerinden çıkarılması , nesneye bir imleç verir, bu da muhtemelen 0eleman dizileri için geçerli olmamalıdır .
Language Lawyer

2
@Bathsheba Sizce kusurlu ifadeler hakkında daha yetkili bir şey olabilir mi?
Dil Avukatı
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.