2009-11-15 38 views
10

merak ediyorum olmadığını realloc daha küçük (sıfırdan farklı) boyutu ile çağrıldığında bir işaretçi değişmez olduğu C veya C++ standart garanti:yeni boyut daha küçükse işaretçiyi hareket ettirebilir mi?

Temelde
size_t n=1000; 
T*ptr=(T*)malloc(n*sizeof(T)); 
//<--do something useful (that won't touch/reallocate ptr of course) 
size_t n2=100;//or any value in [1,n-1] 
T*ptr2=(T*)realloc(ptr,n2*sizeof(T)); 
//<-- are we guaranteed that ptr2==ptr ? 

OS kendi başına karar verebilir biz serbest beri Büyük bir bellek bloğu, hafızayı birleştirmek için tüm realloklardan faydalanmak istiyor ve bir şekilde ptr2'yi mi taşıyor?

cevap

6

realloc ile, hafıza afterwords yaşayacak nerede konusunda kesinlikle hiçbir garanti olsun. Ben libc'in varsayılan malloc'unun sadece hafızayı kopyalayacağına inanıyorum, bu yüzden pratik olarak konuşabilirsiniz. Ama buna güvenme. 0'a eşit bir büyüklükte olan başarıyla tamamlayan

16

http://opengroup.org/onlinepubs/007908775/xsh/realloc.html

, realloc() (muhtemelen taşınan) ayrılan alan bir işaretçiyi geri döndürmektedir.

Hayır, hiçbir garantisi Windows'ta

+1

Bu sayfada daha önce yazıyor ki, "realloc() işlevi, ptr ile gösterilen bellek nesnesinin boyutunu, boyuta göre belirtilen boyuta değiştirir. Nesnenin içeriği, yeni ve daha az olana kadar değişmeden kalır." eski boyutlar: Bellek nesnesinin yeni boyutu, nesnenin hareketini gerektiriyorsa, nesnenin önceki örneğinin alanı boşaltılır. " Harekete hükmetmiyor, ama nispeten olası değil. –

+1

Evet, hala bellekte olan her şeyin hala orada olacağından emin olabilirsiniz, bunu işaretlediğiniz için teşekkürler –

0

C-Runtime bir yığın kapar ve daha sonra bu yığınından bellek ayırır. Dolayısıyla, işletim sistemi bireysel bellek ayırmalarını bilmeyecek ve bu nedenle de etraftakileri hareket ettirmeyecektir.

+1

Bu doğru değil. Visual C çalışma zamanı, bir şey için doğrudan işletim sistemi yığın uygulaması değil. Başka bir deyişle, HeapReAlloc() çağrısı _does_ şeyleri hareket ettirir. –

+1

Dokümanlarınızı iki kez kontrol etmeniz gerekir. Bakınız: http://msdn.microsoft.com/en-us/library/csd157zx.aspx CRT, dahili olarak kullanmak için tek bir işletim sistemi yığını alır. Daha sonra bu yığının alt kısmını ayırır (yani bu yığın içinde tahsisatlar yapmak için Win32 yığın çağrılarını kullanmaz) – DougN

6

, dönem aynı konumu dönecektir garanti realloc yok.

+0

Eğer bu bir yerlerde kesinlikle belirtilmişse güzel olurdu. "X'in gerçekleşmesi garantileniyor" demek, "X'in gerçekleşmesini garanti etmediğini" belirtenlerle aynı değildir. – RoG

4

realloc o uyabilecek bile yerinde bloğu bırakmaları gerekmektedir ve aslında en basit saplama uygulama örneğidir değil nerede o olmayabilir:

  • malloc: sbrk diyoruz.
  • realloc: malloc ve memcpy arayın.
  • free: no-op.

Bu çok saçma gelebilir, ancak bazen gömülü sistemler için daha önce anlattığım gibi bir uygulama aslında en uygun olanıdır.

+0

Başka bir örnek, parçalanmayı önlemek için tüm bitişik tahsislerin aynı boyutta bloklar olduğu bir uygulamadır. Bu durumda, bir 32 bayt bloğu artık eski 4096 bayt bloğuyla aynı konuma ait değil. –

+0

Evet. Bir başka daha gelişmiş örnek, bloğun sol taraftaki komşusunun büzülüp atılmayacağını inceleyen bir uygulama olacaktır. Bu, sonuçta elde edilen boyutun "yeterince küçük" olup olmadığına bakılmaksızın, sağ tarafta önemli bir serbest bloğun oluşturularak oluşturulup oluşturulmayacağıdır. "Bu memcpy" çok pahalı değil ... ve doğru şartlar yerine getirilirse, parçalanmayı önlemek için bloğu yeni bir konuma taşır. –

2

Tüm güncel cevapları (bu cevabın anda) herhangi bir standart belgeye atıfta bulunmayan geliyor bana.

C++ için Working Draft, Standard for Programming Language C++, Document Number: N3337, Date: 2012-01-16, Revises: N3291'a, https://isocpp.org/std/the-standard'a göre, özgür olmayan resmi C++ 11 standart belgesine en yakın ücretsiz belgedir;

2 içindekiler Standart C kütüphanesi başlığında aşağıdaki değişiklikler ile aynıdır: burada 20.6.13 C kütüphanesinde bulmak [Bence listelenen değişiklikler alakalı olmayan soru].

Şimdi biz C standardına ilgili olmalıdır.

https://stackoverflow.com/a/83763/15485'a göre, ücretsiz resmi olmayan C11 standart belgesine en yakın ücretsiz belge Programming languages — C, N1570 Committee Draft — April 12, 2011 ISO/IEC 9899:201x; Burada 7.22.3'de bulabilirsiniz.5 realloc fonksiyonu:

4 realloc fonksiyonu ( eski nesne için bir işaretçi olarak aynı değere sahip olabilir ) yeni nesne için bir işaretçiyi geri döndürmektedir, bir boş işaretçi yeni halinde nesne tahsis edilemedi.

Ben ana dili İngilizce olan bir konuşmacı değilim ve "belkide" anlamını yorumlamak size kalmış.

+4

Ben ana dili İngilizce olan bir konuşmacıyım (ve C standardına oldukça aşina). Belirtilen metin, yeni işaretçinin eski işaretçi ile aynı değere sahip olabileceğini veya olmayabileceğini, bunun boyutuna bağlı olduğunu ima etmeyeceğini söylüyor. Bir mantık (standartta belirtilmemiş), bir uygulamanın parçalanmayı azaltmak ve gelecekteki tahsisleri başarma olasılığını arttırmak için daha küçük bir parçayı farklı bir yere ayırabilmesidir. Bazı durumlarda taşınılmadığının bir garantisi olması için, bu standartta açıkça belirtilmelidir. Öyle değil. –