C ++ 'da statik dizi ve dinamik dizi


91

C ++ 'da statik dizi ile dinamik dizi arasındaki fark nedir?

Sınıfım için bir atama yapmam gerekiyor ve statik dizileri değil, sadece dinamik dizileri kullanmamı söylüyor. Kitaba ve internete baktım, ama anlamıyor gibiyim.

Statiğin derleme zamanında ve dinamik olarak çalışma zamanında oluşturulduğunu düşündüm, ancak bunu bellek ayırma ile karıştırıyor olabilirim.

C ++ 'da statik dizi ve dinamik dizi arasındaki farkı açıklayabilir misiniz?


1
Statik, dinamiğin tersi değildir. Ya kullandığınız kitap berbattır ya da bağlamından çıkarırsınız. Bunu açıklığa kavuşturmak için aşağıya yeni bir cevap ekleyeceğim.
Joshua Clayton

3
Şu sorudaki şemaya bakın: stackoverflow.com/a/11698458/1143274 Statik diziler yığın veya yığın üzerinde tahsis edilmemiştir.
Evgeni Sergeev

* sabit dizi - dinamik dizi
csguy

Yanıtlar:


102

Yığın üzerinde yerel diziler oluşturulur ve otomatik depolama sürelerine sahiptir - belleği manuel olarak yönetmeniz gerekmez, ancak işlev sona erdiğinde yok edilirler. Mutlaka sabit bir boyuta sahipler:

int foo[10];

operator new[]Dinamik depolama süresine sahip olan diziler yığın üzerinde depolanır (teknik olarak "ücretsiz depo"). Herhangi bir boyuta sahip olabilirler, ancak yığın çerçevesinin bir parçası olmadıkları için bunları kendiniz ayırmanız ve serbest bırakmanız gerekir:

int* foo = new int[10];
delete[] foo;

18
Bu doğru, ancak yalnızca nasıl çalıştığını göstermek için. Lütfen bunu gerçek kodda yapmayın, bunun yerine bir std :: vektör kullanın.
Eddy Pronk

23
@Eddy: Bir vektörün gerekli olup olmadığı duruma bağlıdır
Casebash

6
@Casebash: Hangi durumda bir diziyi tercih edersiniz? "Her zaman diziler yerine vektörleri veya değerleri kullanmayı tercih etmelisiniz." - Herb Sutter (Daha olağanüstü C ++)
Eddy Pronk

16
@EddyPronk Bellek parçalanması nedenlerinden dolayı, bir tür havuz olarak sabit bir dizi kullanılabilir. Her durum yığın gerektirmez, yığın tabanlı dizileri kullanmanın özel avantajları vardır. Std :: vector'e altın bir çekiç, yaygın bir anti-model gibi davranıyorsunuz.
void.pointer

4
@EddyPronk: Herb Sutter'ın dinamik diziler anlamına geldiğinden oldukça eminim, kendinize ait int* foo = new int[N]olması gerektiği gibi deleteve bu nedenle istisna durumunda dikkatli olun. Statik dizilerde bu sorunlar yoktur.
Alexander Malakhov

31

static, C ve C ++ 'da bir anahtar kelimedir, bu nedenle genel bir tanımlayıcı terimden ziyade, statik bir değişkene veya diziye uygulandığında çok özel bir anlama sahiptir. Karışıklığı birleştirmek için, ayrı bağlamlarda üç farklı anlamı vardır. Bu nedenle, statik bir dizi sabit veya dinamik olabilir.

Açıklamama izin ver:

İlki C ++ 'ya özgüdür:

  • Statik sınıf üyesi, yapıcıyla başlatılmayan veya yıkıcıyla silinmeyen bir değerdir. Bu, üyenin başka bir şekilde başlatılması ve bakımı yapılması gerektiği anlamına gelir. statik üye, null olarak başlatılan işaretçiler olabilir ve daha sonra bir kurucu ilk çağrıldığında tahsis edilebilir. (Evet, bu statik ve dinamik olur)

İki tanesi C'den miras alınır:

  • Bir işlev içinde, statik değişken, bellek konumu işlev çağrıları arasında korunan değişkendir. Yalnızca bir kez başlatıldığı ve işlev çağrıları arasında değerini koruduğu için statiktir (statik kullanımı bir işlevi evresel olmayan yapar, yani evreli olmayan)

  • İşlevlerin dışında bildirilen statik değişkenler, yalnızca aynı modül içinden erişilebilen global değişkenlerdir (diğer # include'lerin olduğu kaynak kod dosyası)

Sormak istediğiniz soru (sanırım) dinamik diziler ile sabit veya derleme zamanı dizileri arasındaki farkın ne olduğudur. Bu daha kolay bir sorudur, derleme zamanı dizileri önceden belirlenir (program derlendiğinde) ve bir işlev yığını çerçevesinin parçasıdır. Ana işlev çalışmadan önce tahsis edilirler. dinamik diziler çalışma zamanında "new" anahtar sözcüğü (veya C'den malloc ailesi) ile tahsis edilir ve boyutları önceden bilinmemektedir. dinamik ayırmalar, program çalışmayı durdurana kadar otomatik olarak temizlenmez.


4
+1, cevabınız en doğru ve kesin ve daha fazla oy almış olmalıydı.
Z bozonu

new[]Operatörle dizinin boyutunu bildirirseniz, boyutun çalışma zamanına kadar bilinmemesi nasıl olur? ieint* p = new int[10]
wulfgarpro

"Ana fonksiyon çalışmadan önce tahsis edilirler." Yığın değişkenleri neden ilgili blok girilmeden önce tahsis edilir?
AlwaysLearning

Yığın değişkenleri (genellikle bir işlevdeki yerel değişkenler), bir yığın çerçevesi içinde önceden tanımlanmış bir boyuta ve konuma sahiptir ve tüm yığın, ana işlev, @AlwaysLearning çalıştırılmadan önce tahsis edilir. İşlev çağrısı aracılığıyla bir yığın çerçevesi girildiğinde, yığın işaretçisi güncellenir, ancak yeni yığın çerçevesi yığının içindedir. Daha fazla yığın tahsis edilmez. Aslında, çok büyük değişkenler (örneğin dev bir dizi) veya aynı anda çok fazla işlev çağrısı açılması, bu sitenin adlandırıldığı bir yığın taşmasına neden olur.
Joshua Clayton

@JoshuaClayton Bunun doğru olamayacağını düşünüyorum. Bir özyinelemeli işlev için kaç kez girileceğini bilmediğinizde yığın çerçevelerini (çoğul olana dikkat edin) nasıl ayırabilirsiniz?
AlwaysLearning

11

Sınıfınızda kullanılan anlambilimin kafa karıştırıcı olduğunu düşünüyorum. Muhtemelen "statik" ile kastedilen basitçe "sabit boyuttur" ve muhtemelen "dinamik" ile "değişken boyut" kastedilmektedir. Bu durumda, sabit boyutlu bir dizi şöyle görünebilir:

int x[10];

ve "dinamik" bir yapı, temeldeki depolamanın çalışma zamanında artırılmasına veya azaltılmasına izin veren herhangi bir yapı olabilir. Çoğu zaman, std::vectorC ++ standart kitaplığındaki sınıf yeterli olacaktır. Bunu şu şekilde kullanın:

std::vector<int> x(10); // this starts with 10 elements, but the vector can be resized.

std::vectorolan operator[]bir dizi olarak aynı anlamda kullanabilirsiniz, böylece tanımlanmış.


1
"Dinamik dizi" ile basitçe dinamik olarak ayrılmış bir diziyi kastettiklerinin oldukça açık olduğunu düşünüyorum (yani, boyutun çalışma zamanında dinamik olarak belirtilebildiği bir dizi). Beğennew int[10]
jalf

@jalf: 'Statik' terimi hakkında daha çok endişeliydim. Tutarlılık adına "dinamik diziyi" ayrılmış veya değişken boyutlu bir dizi olarak adlandırmayı tercih ediyorum.
Ben Collins

İyi nokta, çünkü statik bir dizi otomatik olabilir ve yığın üzerinde uygulanabilir veya global olabilir ve bir veri bölümünde uygulanabilir. Her ikisi de statiktir, ancak bunlara erişen kod dahili olarak çok farklı olabilir.
Z bozonu

9

Statik dizilere derleme zamanında bellek ayrılır ve bellek yığın üzerinde ayrılır. Oysa dinamik dizilere çalışma zamanında bellek tahsis edilir ve bellek öbekten ayrılır.

int arr[] = { 1, 3, 4 }; // static integer array.   
int* arr = new int[3]; // dynamic integer array.

5
Global dizi, statik bir dizidir ve yığından değil, bir veri bölümünde uygulanır.
Z bozonu

8

Terimlerin ne anlama geldiğine dair net tanımlara sahip olmak önemlidir. Ne yazık ki, statik ve dinamik dizilerin ne anlama geldiğine dair birden fazla tanım var gibi görünüyor.

Statik değişkenler , statik bellek tahsisi kullanılarak tanımlanan değişkenlerdir . Bu, C / C ++ 'dan bağımsız genel bir kavramdır. C / C ++ 'da aşağıdaki gibi global, dosya veya yerel kapsamda statik değişkenler oluşturabiliriz:

int x[10]; //static array with global scope
static int y[10]; //static array with file scope
foo() {
    static int z[10]; //static array with local scope

Otomatik değişkenler genellikle yığın tabanlı bellek tahsisi kullanılarak uygulanır . C / C ++ 'da şu şekilde otomatik bir dizi oluşturulabilir:

foo() {
    int w[10]; //automatic array

Ne bu diziler, x, y, zve wortak noktası bunların her biri için boyut sabittir ve derleme zamanında tanımlanan olmasıdır.

Otomatik dizi ile statik dizi arasındaki farkı anlamanın önemli olmasının nedenlerinden biri, statik depolamanın genellikle bir nesne dosyasının veri bölümünde (veya BSS bölümünde ) uygulanması ve derleyicinin dizilere erişmek için mutlak adresler kullanabilmesidir. yığın tabanlı depolamayla bu imkansızdır.

Genellikle dinamik dizi ile kastedilen, yeniden boyutlandırılabilen değil, çalışma zamanında belirlenen sabit bir boyuta sahip dinamik bellek ayırma kullanılarak uygulanan bir dizidir . C ++ 'da bu, newoperatör kullanılarak yapılır .

foo() {
   int *d = new int[n]; //dynamically allocated array with size n     

Ancak, aşağıdakileri kullanarak çalışma zamanında tanımlanan bir düzeltme boyutuna sahip otomatik bir dizi oluşturmak mümkündür alloca:

foo() {
    int *s = (int*)alloca(n*sizeof(int))

Gerçek bir dinamik dizi std::vectoriçin C ++ 'da olduğu gibi (veya C'de değişken uzunluklu bir dizi ) kullanılmalıdır.

OP'nin sorusundaki görev için ne ifade edildi? Sanırım, istenen şeyin statik veya otomatik bir dizi değil, newoperatörü kullanarak dinamik bellek tahsisi veya örn std::vector.


3

Bence bu bağlamda, boyutun sabit olması anlamında statik olduğu anlamına geliyor. Std :: vector kullanın. Resize () işlevi vardır.


2

Boyutun kullanıcı tarafından çalışma zamanında ayarlandığı, ancak daha sonra sabitlendiği bir sözde dinamik diziniz olabilir.

int size;
cin >> size;
int dynamicArray[size];

Standart C ++ 'ın parçası değildir (C99'da ve gcc için bir derleyici uzantısı olarak).
crashmstr

1

Statik Dizi :

  1. Statik dizilere derleme zamanında bellek ayrılır.
  2. Boyut sabittir.
  3. Yığın bellek alanında bulunur.
  4. Örneğin. : int dizi [10]; // boyut 10 dizisi

Dinamik Dizi:

  1. Bellek, çalışma zamanında tahsis edilir.
  2. Boyut sabit değil.
  3. Yığın bellek alanında bulunur.
  4. Örneğin. : int * dizi = new int [10];

0

Evet, statik dizi, çalışma zamanında dinamik dizinin oluşturulduğu derleme zamanında yaratılır. Fark, bellek konumlarıyla ilgili olduğunda, statik yığın üzerinde bulunur ve dinamik yığın üzerinde oluşturulur. Yığın üzerinde bulunan her şey, .net çerçevesinde olduğu gibi çöp toplayıcı mevcut olana kadar bellek yönetimine ihtiyaç duyar, aksi takdirde bellek sızıntısı riski vardır.


0

Statik dizi: Verimlilik. Dinamik ayırma veya serbest bırakmaya gerek yoktur.

C, C ++ 'da statik değiştirici içeren işlevde bildirilen diziler statiktir. Örnek: statik int foo [5];


1
@admdrew, bu doğru ama soru asla iyi cevaplanmadı. En iyi cevap Joshua Clayton'ın cevabı ama bence daha iyi bir cevap bu stackoverflow.com/questions/17775066/…
Z bozonu

@Zboson Bilmekte fayda var, teşekkürler. Heh ve ben bu yorumu neredeyse bir yıl önce yaptığımı fark ettik.
admdrew

-3

dizinin yan tarafındaki elemanların verilmesiyle oluşan statik düzen

dizinin yan tarafındaki öğeleri vermeden dinamik aralık

misal:

     char a[10]; //static array
       char a[];  //dynamic array

Sanırım doğru söyledi. Dizinin tam uzunluğunu belirlediğinizde, bu statik bir dizidir ve uzunluk vermediğinizde dinamik bir dizidir. ama İngilizce yazmayı bilmediği için insanlar bu cevabı işaretliyor.
muhammed tayyab
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.