Perbedaan antara alokasi memori statis dan alokasi memori dinamis

Jawaban:

98

Ada tiga jenis alokasi - statis, otomatis, dan dinamis.

Alokasi Statis artinya, memori untuk variabel Anda dialokasikan saat program dimulai. Ukurannya tetap saat program dibuat. Ini berlaku untuk variabel global, variabel cakupan file, dan variabel yang memenuhi syarat dengan staticfungsi dalam yang ditentukan.

Alokasi memori otomatis terjadi untuk variabel (non-statis) yang ditentukan di dalam fungsi, dan biasanya disimpan di stack (meskipun standar C tidak mengamanatkan bahwa stack digunakan). Anda tidak perlu mencadangkan memori ekstra untuk menggunakannya, tetapi di sisi lain, juga memiliki kendali terbatas atas masa pakai memori ini. Misalnya: variabel otomatis dalam suatu fungsi hanya ada di sana sampai fungsi tersebut selesai.

void func() {
    int i; /* `i` only exists during `func` */
}

Alokasi memori dinamis sedikit berbeda. Anda sekarang mengontrol ukuran pasti dan masa pakai lokasi memori ini. Jika Anda tidak membebaskannya, Anda akan mengalami kebocoran memori, yang dapat menyebabkan aplikasi Anda macet, karena pada suatu titik waktu, sistem tidak dapat mengalokasikan lebih banyak memori.

int* func() {
    int* mem = malloc(1024);
    return mem;
}

int* mem = func(); /* still accessible */

Pada contoh atas, memori yang dialokasikan masih valid dan dapat diakses, meskipun fungsinya dihentikan. Ketika Anda selesai dengan memori, Anda harus membebaskannya:

free(mem);
Constantinius
sumber
2
Yakin Anda memiliki kendali atas masa pakai variabel ... Andalah yang menentukan cakupannya, bukan?
Luchian Grigore
Tentu saja, tapi bukan itu yang saya maksud. Anda tidak dapat memperpanjang umur variabel untuk hidup lebih lama dari ruang lingkupnya. Tapi mungkin saya harus menjelaskannya dalam jawaban saya. Terima kasih
Constantinius
5
-1 Jawaban ini salah. Anda membingungkan variabel statis dan otomatis .
brice
2
Kalimat Anda sendiri berbunyi: " Alokasi Statis artinya, memori untuk variabel Anda dialokasikan secara otomatis " Ini salah . Silakan lihat apa yang dikatakan halaman manual untuk GNU's libc tentangnya.
brice
1
@EliBendersky Ini diucapkan ulang sekarang. Periksa apakah sekarang sudah benar.
Suraj Jain
120

Ini adalah pertanyaan wawancara standar:

Alokasi memori dinamis

Apakah memori dialokasikan saat runtime menggunakan calloc(), malloc()dan teman. Terkadang juga disebut sebagai memori 'heap', meskipun tidak ada hubungannya dengan struktur data heap ref .

int * a = malloc(sizeof(int));

Memori heap bertahan hingga free()dipanggil. Dengan kata lain, Anda mengontrol umur variabel.

Alokasi memori otomatis

Inilah yang umumnya dikenal sebagai memori 'tumpukan', dan dialokasikan saat Anda memasuki cakupan baru (biasanya saat fungsi baru didorong di tumpukan panggilan). Setelah Anda keluar dari ruang lingkup, nilai alamat memori otomatis tidak ditentukan, dan mengaksesnya adalah kesalahan .

int a = 43;

Perhatikan bahwa ruang lingkup tidak selalu berarti fungsi. Cakupan bisa bersarang di dalam suatu fungsi, dan variabel hanya akan berada dalam cakupan di dalam blok tempat ia dideklarasikan. Perhatikan juga bahwa di mana memori ini dialokasikan tidak ditentukan. (Pada sistem yang waras, itu akan ada di tumpukan, atau mendaftar untuk pengoptimalan)

Alokasi memori statis

Dialokasikan pada waktu kompilasi * , dan masa pakai variabel dalam memori statis adalah masa pakai program .

Di C, memori statis dapat dialokasikan menggunakan statickata kunci. Cakupannya hanya unit kompilasi.

Segalanya menjadi lebih menarik ketika externkata kunci dipertimbangkan . Ketika sebuah externvariabel didefinisikan , kompilator mengalokasikan memori untuknya. Ketika sebuah externvariabel dideklarasikan , compiler mengharuskan variabel tersebut didefinisikan di tempat lain. Kegagalan mendeklarasikan / mendefinisikan externvariabel akan menyebabkan masalah penautan, sedangkan kegagalan untuk mendeklarasikan / mendefinisikan staticvariabel akan menyebabkan masalah kompilasi.

dalam ruang lingkup file, kata kunci statis adalah opsional (di luar fungsi):

int a = 32;

Tapi tidak dalam ruang lingkup fungsi (di dalam fungsi):

static int a = 32;

Secara teknis, externdan staticdua kelas variabel yang terpisah di C.

extern int a; /* Declaration */
int a; /* Definition */

* Catatan tentang alokasi memori statis

Agak membingungkan untuk mengatakan bahwa memori statis dialokasikan pada waktu kompilasi, terutama jika kita mulai mempertimbangkan bahwa mesin kompilasi dan mesin host mungkin tidak sama atau bahkan mungkin tidak menggunakan arsitektur yang sama.

Mungkin lebih baik untuk berpikir bahwa alokasi memori statis ditangani oleh kompilator daripada dialokasikan pada waktu kompilasi .

Misalnya kompilator dapat membuat databagian besar dalam biner yang dikompilasi dan ketika program dimuat di memori, alamat di dalamdatasegmen program akan digunakan sebagai lokasi dari memori yang dialokasikan. Ini memiliki kelemahan yang nyata yaitu membuat biner yang dikompilasi menjadi sangat besar jika menggunakan banyak memori statis. Dimungkinkan untuk menulis biner multi-gigabyte yang dihasilkan dari kurang dari setengah lusin baris kode. Pilihan lainnya adalah kompilator memasukkan kode inisialisasi yang akan mengalokasikan memori dengan cara lain sebelum program dijalankan. Kode ini akan bervariasi sesuai dengan platform dan OS target. Dalam praktiknya, kompiler modern menggunakan heuristik untuk memutuskan opsi mana yang akan digunakan. Anda dapat mencobanya sendiri dengan menulis program C kecil yang mengalokasikan array statis besar dari item 10k, 1m, 10m, 100m, 1G atau 10G. Bagi banyak penyusun, ukuran biner akan terus bertambah secara linier dengan ukuran larik, dan melewati titik tertentu,

Daftarkan Memori

Kelas memori terakhir adalah variabel 'register'. Seperti yang diharapkan, variabel register harus dialokasikan pada register CPU, tetapi keputusan sebenarnya diserahkan kepada compiler. Anda tidak boleh mengubah variabel register menjadi referensi dengan menggunakan address-of.

register int meaning = 42;
printf("%p\n",&meaning); /* this is wrong and will fail at compile time. */

Kebanyakan kompiler modern lebih pintar daripada Anda dalam memilih variabel mana yang harus dimasukkan ke dalam register :)

Referensi:

brice
sumber
3
Catatan: Saya menyarankan int * a = malloc(sizeof(*a));sebagai gantinya, untuk menghindari pengulangan tipe a. Ini membuat segalanya lebih mudah jika ada jenis aperubahan.
Shahbaz
1
Sebenarnya ini disebut heap tetapi tidak ada hubungannya dengan struktur data heap. Tumpukan dalam hal ini berarti tempat yang berantakan
dinamis pada
2
"Alokasi memori statis ... dialokasikan pada waktu kompilasi" Apakah maksud Anda ukuran alokasi ditentukan pada waktu kompilasi? Bukankah penyisihan memori hanya terjadi saat runtime?
lf215
Hai, saya ragu, Jika Anda masih merespons :(. Bagaimana dengan alokasi memori otomatis? Akankah kompilator juga menyimpan alamat di bagian data untuk variabel lokal ini dan meneruskannya ke yang dapat dieksekusi. Dan ketika kode dijalankan (dan memasuki ruang lingkup ) alamat-alamat ini sebenarnya akan digunakan sebagai lokasi memori yang dialokasikan. Atau apakah itu benar-benar dialokasikan hanya pada waktu proses, tanpa pembuatan alamat dan penanganan apa pun oleh kompiler saya?
LocalHost
1
@LocalHost Variabel otomatis dibatasi sepanjang konteks (tanda kurung kurawal) di mana mereka telah ditentukan. yang biasanya dialokasikan di stack panggilan saat runtime. Ini pasti tidak disimpan di bagian data. Anda dapat membaca standar C18 di sini: (6.2.4.5-7) web.archive.org/web/20181230041359/http://www.open-std.org/jtc1/...
brice
3

Alokasi Memori Statis:

  • Variabel dialokasikan secara permanen
  • Alokasi dilakukan sebelum eksekusi program
  • Ini menggunakan struktur data yang disebut tumpukan untuk mengimplementasikan alokasi statis
  • Kurang efisien
  • Tidak ada penggunaan kembali memori

Alokasi Memori Dinamis:

  • Variabel dialokasikan hanya jika unit program menjadi aktif
  • Alokasi dilakukan selama eksekusi program
  • Ini menggunakan struktur data yang disebut heap untuk mengimplementasikan alokasi dinamis
  • Lebih efisien
  • Ada penggunaan kembali memori . Memori dapat dibebaskan jika tidak diperlukan
vinay
sumber
1
"Alokasi Memori Statis [...] Ini menggunakan struktur data yang disebut tumpukan untuk mengimplementasikan alokasi statis" Tidak , itu salah dan menyesatkan. silakan lihat posting saya untuk perbedaan antara alokasi otomatis dan statis. Memori statis dapat menggunakan tumpukan. Ini sangat bergantung pada implementasi, dan beberapa strategi dapat digunakan untuk implementasi yang sama. Saya juga tidak yakin apa yang Anda maksud dengan "Kurang efisien". @Trieu Toan, Anda mengubah arti jawaban ini dengan pengeditan yang buruk.
brice
2

Alokasi memori statis: Kompilator mengalokasikan ruang memori yang diperlukan untuk variabel yang dideklarasikan. Dengan menggunakan alamat operator, alamat yang dicadangkan diperoleh dan alamat ini dapat ditugaskan ke variabel pointer. Karena sebagian besar variabel yang dideklarasikan memiliki memori statis, ini cara menetapkan nilai pointer ke variabel pointer dikenal sebagai alokasi memori statis. memori diberikan selama waktu kompilasi.

Alokasi memori dinamis: Menggunakan fungsi seperti malloc () atau calloc () untuk mendapatkan memori secara dinamis.Jika fungsi ini digunakan untuk mendapatkan memori secara dinamis dan nilai yang dikembalikan oleh fungsi ini ditetapkan ke variabel penunjuk, penetapan tersebut dikenal sebagai memori dinamis alokasi.memory ditetapkan selama run time.

Rajeev Kumar
sumber
1

Perbedaan antara ALOKASI MEMORI STATIK & ALOKASI MEMORI DINAMIS

Memori dialokasikan sebelum eksekusi program dimulai (Selama Kompilasi).
Memori dialokasikan selama eksekusi program.

Tidak ada alokasi memori atau tindakan deallocation yang dilakukan selama Eksekusi.
Memory Binding dibuat dan dihancurkan selama Eksekusi.

Variabel tetap dialokasikan secara permanen.
Dialokasikan hanya jika unit program aktif.

Diterapkan menggunakan tumpukan dan tumpukan.
Diterapkan menggunakan segmen data.

Pointer diperlukan untuk mengakses variabel.
Tidak perlu pointer yang dialokasikan secara dinamis.

Eksekusi lebih cepat dari Dynamic.
Eksekusi lebih lambat dari statis.

Lebih banyak ruang memori diperlukan.
Lebih sedikit ruang memori yang dibutuhkan.

Ebenezer
sumber
1
alokasi memori statis dialokasikan di Stack sementara alokasi memori Dinamis dialokasikan di Heap
Usman Kurd
@UsmanKurd Itu umumnya salah tentang memori statis. Lihat jawabanku.
brice
0

Alokasi memori statis dialokasikan memori sebelum mengeksekusi program pf selama waktu kompilasi. Alokasi memori dinamis adalah memori yang dialokasikan selama eksekusi program pada saat dijalankan.

Ritu maheswari
sumber
-1

Alokasi memori statis. Memori yang dialokasikan akan ditumpuk.

int a[10];

Alokasi memori dinamis. Memori yang dialokasikan akan berada di heap.

int *a = malloc(sizeof(int) * 10);

dan yang terakhir harus bebas d karena tidak ada Pengumpul Sampah (GC) di C.

free(a);
onemach
sumber