Array statis vs. larik dinamis dalam C ++

91

Apa perbedaan antara array statis dan array dinamis di C ++?

Saya harus melakukan tugas untuk kelas saya dan dikatakan untuk tidak menggunakan array statis, hanya array dinamis. Saya sudah mencari di buku dan online, tapi sepertinya saya tidak mengerti.

Saya pikir statis dibuat pada waktu kompilasi dan dinamis pada waktu proses, tetapi saya mungkin salah mengira ini dengan alokasi memori.

Bisakah Anda menjelaskan perbedaan antara array statis dan array dinamis di C ++?

pengguna69514
sumber
1
Statis bukanlah kebalikan dari dinamika. Entah buku yang Anda gunakan jelek, atau Anda mengeluarkannya dari konteks. Saya akan menambahkan jawaban baru di bawah untuk semoga menjernihkan ini.
Joshua Clayton
3
Lihat diagram dalam pertanyaan ini: stackoverflow.com/a/11698458/1143274 Larik statis tidak dialokasikan di tumpukan atau heap.
Evgeni Sergeev
* array tetap vs array dinamis
csguy

Jawaban:

102

Larik lokal dibuat di tumpukan, dan memiliki durasi penyimpanan otomatis - Anda tidak perlu mengelola memori secara manual, tetapi mereka akan dihancurkan ketika fungsinya berakhir. Mereka harus memiliki ukuran tetap:

int foo[10];

Array yang dibuat dengan operator new[]memiliki durasi penyimpanan dinamis dan disimpan di heap (secara teknis disebut "penyimpanan gratis"). Mereka dapat memiliki ukuran apa saja, tetapi Anda perlu mengalokasikan dan membebaskannya sendiri karena mereka bukan bagian dari bingkai tumpukan:

int* foo = new int[10];
delete[] foo;
Michael Mrozek
sumber
18
Ini benar, tetapi hanya untuk menggambarkan cara kerjanya. Harap jangan lakukan ini dalam kode sebenarnya tetapi gunakan std :: vector sebagai gantinya.
Eddy Pronk
23
@ Eddy: Tergantung pada situasi, apakah vektor diperlukan
Casebash
6
@Casebash: Dalam situasi apa Anda lebih memilih array? "Anda harus selalu memilih untuk menggunakan vektor atau deques daripada array." - Herb Sutter (C ++ lebih luar biasa)
Eddy Pronk
16
@EddyPronk Untuk alasan fragmentasi memori, seseorang dapat menggunakan array tetap sebagai semacam kumpulan. Tidak setiap kasus menuntut heap, ada manfaat khusus untuk menggunakan array berbasis tumpukan. Anda memperlakukan vektor std :: sebagai palu emas, anti-pola umum.
void.pointer
4
@EddyPronk: Saya cukup yakin Herb Sutter berarti array dinamis, seperti int* foo = new int[N]yang Anda miliki untuk deletediri Anda sendiri dan karenanya berhati-hatilah saat ada pengecualian. Array statis tidak memiliki masalah ini.
Alexander Malakhov
31

statis adalah kata kunci dalam C dan C ++, jadi daripada istilah deskriptif umum, statis memiliki arti yang sangat spesifik bila diterapkan pada variabel atau larik. Untuk menambah kebingungan, kata ini memiliki tiga arti berbeda dalam konteks yang terpisah. Karena itu, array statis dapat berupa tetap atau dinamis.

Izinkan saya menjelaskan:

Yang pertama adalah khusus C ++:

  • Anggota kelas statis adalah nilai yang tidak dibuat dengan konstruktor atau dihapus dengan destruktor. Ini berarti anggota harus diinisialisasi dan dipertahankan dengan cara lain. anggota statis dapat berupa pointer yang diinisialisasi ke null dan kemudian dialokasikan saat pertama kali konstruktor dipanggil. (Ya, itu akan menjadi statis dan dinamis)

Dua diwarisi dari C:

  • dalam suatu fungsi, variabel statis adalah variabel yang lokasi memorinya dipertahankan di antara pemanggilan fungsi. Ini statis karena diinisialisasi hanya sekali dan mempertahankan nilainya di antara pemanggilan fungsi (penggunaan statika membuat fungsi non-reentrant, yaitu bukan threadsafe)

  • variabel statis yang dideklarasikan di luar fungsi adalah variabel global yang hanya dapat diakses dari dalam modul yang sama (file kode sumber dengan # include lainnya)

Pertanyaan (saya pikir) yang ingin Anda tanyakan adalah apa perbedaan antara array dinamis dan array tetap atau waktu kompilasi. Itu adalah pertanyaan yang lebih mudah, array waktu kompilasi ditentukan sebelumnya (ketika program dikompilasi) dan merupakan bagian dari bingkai tumpukan fungsi. Mereka dialokasikan sebelum fungsi utama dijalankan. array dinamis dialokasikan saat runtime dengan kata kunci "baru" (atau keluarga malloc dari C) dan ukurannya tidak diketahui sebelumnya. alokasi dinamis tidak secara otomatis dibersihkan sampai program berhenti berjalan.

Joshua Clayton
sumber
4
+1, jawaban Anda adalah yang paling akurat dan tepat dan seharusnya menerima lebih banyak suara.
Z boson
Jika Anda mendeklarasikan ukuran array dengan new[]operator, bagaimana mungkin ukurannya tidak diketahui hingga runtime? yaituint* p = new int[10]
wulfgarpro
"Mereka dialokasikan sebelum fungsi utama dijalankan." Mengapa mengalokasikan variabel tumpukan sebelum blok yang relevan dimasukkan?
AlwaysLearning
Variabel tumpukan (umumnya variabel lokal dalam suatu fungsi) memiliki ukuran dan posisi yang telah ditentukan sebelumnya dalam bingkai tumpukan dan seluruh tumpukan dialokasikan sebelum fungsi utama berjalan, @AlwaysLearning. Saat memasuki bingkai tumpukan melalui panggilan fungsi, penunjuk tumpukan diperbarui, tetapi bingkai tumpukan baru ada di dalam tumpukan. Tidak ada lagi tumpukan yang dialokasikan. Faktanya, variabel yang terlalu besar (larik raksasa misalnya) atau terlalu banyak pemanggilan fungsi yang dibuka pada saat yang sama menghasilkan luapan tumpukan, yang menjadi nama situs ini.
Joshua Clayton
@ JoshuaClay Saya pikir ini tidak mungkin benar. Bagaimana Anda bisa mengalokasikan frame stack (perhatikan bentuk jamak) untuk fungsi rekursif ketika Anda tidak tahu berapa kali itu akan dimasukkan?
AlwaysLearning
11

Saya pikir semantik yang digunakan di kelas Anda membingungkan. Apa yang mungkin dimaksud dengan 'statis' hanyalah "ukuran konstan", dan apa yang mungkin dimaksud dengan "dinamis" adalah "ukuran variabel". Dalam kasus itu, array ukuran konstan mungkin terlihat seperti ini:

int x[10];

dan struktur yang "dinamis" hanyalah jenis struktur apa pun yang memungkinkan penyimpanan yang mendasari ditingkatkan atau dikurangi pada waktu proses. Biasanya, std::vectorkelas dari pustaka standar C ++ sudah cukup. Gunakan seperti ini:

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

std::vectortelah operator[]ditentukan, sehingga Anda dapat menggunakannya dengan semantik yang sama sebagai array.

Ben Collins
sumber
1
Saya pikir itu cukup jelas bahwa dengan "array dinamis" yang mereka maksud adalah array yang dialokasikan secara dinamis (yaitu, yang ukurannya dapat ditentukan secara dinamis, saat runtime). Sepertinew int[10]
jalf
@jalf: Saya lebih memperhatikan istilah 'statis'. Saya lebih suka menyebut "larik dinamis" sebagai larik ukuran variabel atau yang dialokasikan demi konsistensi.
Ben Collins
Poin yang bagus karena array statis bisa otomatis dan diimplementasikan di stack atau global dan diimplementasikan di bagian data. Keduanya statis tetapi secara internal kode yang mengaksesnya bisa sangat berbeda.
Z boson
9

Array statis dialokasikan memori pada waktu kompilasi dan memori dialokasikan pada stack. Sedangkan array dinamis dialokasikan memori pada saat runtime dan memori dialokasikan dari heap.

int arr[] = { 1, 3, 4 }; // static integer array.   
int* arr = new int[3]; // dynamic integer array.
Jagannath
sumber
5
Larik global adalah larik statis dan diimplementasikan di bagian data dan bukan dari tumpukan.
Z boson
8

Penting untuk memiliki definisi yang jelas tentang arti istilah. Sayangnya tampaknya ada beberapa definisi tentang apa yang dimaksud dengan array statis dan dinamis.

Variabel statis adalah variabel yang ditentukan menggunakan alokasi memori statis . Ini adalah konsep umum yang tidak bergantung pada C / C ++. Di C / C ++ kita dapat membuat variabel statis dengan cakupan global, file, atau lokal seperti ini:

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

Variabel otomatis biasanya diimplementasikan menggunakan alokasi memori berbasis tumpukan . Array otomatis dapat dibuat di C / C ++ seperti ini:

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

Apa yang dimiliki array ini x, y, z, dan wkesamaannya adalah bahwa ukuran untuk masing-masing array tersebut tetap dan ditentukan pada waktu kompilasi.

Salah satu alasan penting untuk memahami perbedaan antara array otomatis dan array statis adalah karena penyimpanan statis biasanya diimplementasikan di bagian data (atau bagian BSS ) dari file objek dan kompiler dapat menggunakan alamat absolut untuk mengakses array. yang tidak mungkin dilakukan dengan penyimpanan berbasis tumpukan.

Yang biasanya dimaksud dengan array dinamis bukanlah yang dapat diubah ukurannya tetapi yang diimplementasikan menggunakan alokasi memori dinamis dengan ukuran tetap yang ditentukan pada waktu proses. Di C ++ ini dilakukan dengan menggunakan newoperator .

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

Tetapi dimungkinkan untuk membuat larik otomatis dengan ukuran perbaikan yang ditentukan saat runtime menggunakan alloca:

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

Untuk array dinamis sejati, seseorang harus menggunakan sesuatu seperti std::vectordi C ++ (atau array panjang variabel di C ).

Apa yang dimaksud dengan penugasan dalam pertanyaan OP? Saya pikir sudah jelas bahwa apa yang diinginkan bukanlah array statis atau otomatis tetapi yang baik menggunakan alokasi memori dinamis menggunakan newoperator atau array berukuran tidak tetap menggunakan mis std::vector.

Z boson
sumber
3

Menurut saya dalam konteks ini artinya statis dalam arti ukurannya tetap. Gunakan std :: vector. Ini memiliki fungsi resize ().

Eddy Pronk
sumber
2

Anda bisa memiliki larik dinamis semu di mana ukurannya ditetapkan oleh pengguna pada waktu proses, tetapi kemudian diperbaiki setelah itu.

int size;
cin >> size;
int dynamicArray[size];
Joshua Oliphant
sumber
Bukan bagian dari C ++ standar (di C99 dan sebagai ekstensi kompilator untuk gcc).
crashmstr
1

Array Statis :

  1. Array statis dialokasikan memori pada waktu kompilasi.
  2. Ukuran tetap.
  3. Terletak di ruang memori tumpukan.
  4. Misalnya. : larik int [10]; // larik berukuran 10

Array Dinamis:

  1. Memori dialokasikan pada waktu berjalan.
  2. Ukuran tidak tetap.
  3. Terletak di ruang memori Heap.
  4. Misalnya. : int * array = new int [10];
Tejashree Kudale
sumber
0

Ya benar, array statis dibuat pada waktu kompilasi dimana array dinamis dibuat pada waktu proses. Sedangkan perbedaan sejauh menyangkut lokasi memorinya, statis terletak di stack dan dinamika dibuat di heap. Segala sesuatu yang ditempatkan di heap memerlukan manajemen memori sampai dan kecuali pengumpul sampah seperti dalam kasus .net framework ada, jika tidak ada risiko kebocoran memori.

Aadil Imran
sumber
0

Array statis: Efisiensi. Tidak ada alokasi dinamis atau deallocation diperlukan.

Array yang dideklarasikan dalam C, C ++ dalam fungsi termasuk pengubah statis bersifat statis. Contoh: static int foo [5];

Khuê Phạm
sumber
1
@admdrew, itu benar tapi pertanyaannya tidak pernah dijawab dengan baik. Jawaban terbaik adalah jawaban Joshua Clayton tetapi saya pikir jawaban yang lebih baik adalah yang satu ini stackoverflow.com/questions/17775066/…
Z boson
@Zboson Senang mengetahuinya, terima kasih. Heh dan saya baru menyadari saya membuat komentar itu hampir setahun yang lalu sekarang.
admdrew
-3

susunan statis berarti dengan memberikan elemen di sisi array

arar dinamis berarti tanpa memberikan elemen di samping larik

contoh:

     char a[10]; //static array
       char a[];  //dynamic array
karthik
sumber
Saya pikir dia berkata benar. Ketika Anda memiliki panjang yang tepat untuk array, itu adalah array statis dan ketika Anda tidak memberi panjang, itu adalah array dinamis. tetapi karena dia tidak tahu bagaimana menulis bahasa Inggris, itulah mengapa orang menandai jawaban ini.
muhammad tayyab