Saya mengerti cara kerja malloc (). Pertanyaan saya adalah, saya akan melihat hal-hal seperti ini:
#define A_MEGABYTE (1024 * 1024)
char *some_memory;
size_t size_to_allocate = A_MEGABYTE;
some_memory = (char *)malloc(size_to_allocate);
sprintf(some_memory, "Hello World");
printf("%s\n", some_memory);
free(some_memory);
Saya menghilangkan pengecekan kesalahan demi singkatnya. Pertanyaan saya adalah, tidak bisakah Anda melakukan hal di atas dengan menginisialisasi pointer ke beberapa penyimpanan statis di memori? mungkin:
char *some_memory = "Hello World";
Pada titik manakah Anda benar-benar perlu mengalokasikan memori sendiri daripada mendeklarasikan / menginisialisasi nilai yang perlu Anda pertahankan?
c
memory
memory-management
randombits
sumber
sumber
malloc()
dapat gagal!Jawaban:
membuat pointer ke konstanta string. Itu berarti string "Hello World" akan berada di suatu tempat di bagian memori hanya-baca dan Anda hanya memiliki penunjuk ke sana. Anda dapat menggunakan string sebagai baca-saja. Anda tidak dapat mengubahnya. Contoh:
Apakah mencari masalah.
Di samping itu
mengalokasikan array char (variabel) dan some_memory menunjuk ke memori yang dialokasikan. Sekarang array ini membaca dan menulis. Sekarang Anda dapat melakukan:
dan konten array berubah menjadi "hello World"
sumber
const char *s = "hi";
Bukankah ini sebenarnya dipersyaratkan oleh standar?const char const* s;
Untuk contoh yang tepat, malloc tidak banyak berguna.
Alasan utama malloc diperlukan adalah ketika Anda memiliki data yang harus memiliki masa pakai yang berbeda dari cakupan kode. Kode Anda memanggil malloc dalam satu rutinitas, menyimpan penunjuk di suatu tempat dan akhirnya menelepon gratis di rutinitas yang berbeda.
Alasan kedua adalah bahwa C tidak memiliki cara untuk mengetahui apakah ada cukup ruang tersisa di tumpukan untuk alokasi. Jika kode Anda harus 100% kuat, lebih aman menggunakan malloc karena kode Anda dapat mengetahui alokasi gagal dan menanganinya.
sumber
malloc adalah alat yang luar biasa untuk mengalokasikan, mengalokasikan ulang, dan membebaskan memori saat runtime, dibandingkan dengan deklarasi statis seperti contoh hello world Anda, yang diproses pada waktu kompilasi dan karenanya tidak dapat diubah ukurannya.
Oleh karena itu, Malloc selalu berguna saat Anda menangani data berukuran arbitrer, seperti membaca konten file atau berurusan dengan soket dan Anda tidak mengetahui panjang data yang akan diproses.
Tentu saja, dalam contoh sepele seperti yang Anda berikan, malloc bukanlah "alat yang tepat untuk pekerjaan yang tepat", tetapi untuk kasus yang lebih kompleks (misalnya membuat larik berukuran arbitrer pada waktu proses), ini adalah satu-satunya cara untuk Pergilah.
sumber
Jika Anda tidak mengetahui ukuran pasti dari memori yang perlu Anda gunakan, Anda memerlukan alokasi dinamis (
malloc
). Contohnya mungkin ketika pengguna membuka file di aplikasi Anda. Anda perlu membaca konten file ke dalam memori, tetapi tentu saja Anda tidak mengetahui ukuran file sebelumnya, karena pengguna memilih file tersebut di tempat, saat runtime. Jadi pada dasarnya Anda perlumalloc
ketika Anda tidak mengetahui ukuran data yang Anda kerjakan sebelumnya. Setidaknya itulah salah satu alasan utama penggunaanmalloc
. Dalam contoh Anda dengan string sederhana yang sudah Anda ketahui ukurannya pada waktu kompilasi (ditambah Anda tidak ingin mengubahnya), tidak masuk akal untuk mengalokasikannya secara dinamis.Sedikit keluar dari topik, tapi ... Anda harus sangat berhati-hati agar tidak menyebabkan kebocoran memori saat menggunakan
malloc
. Pertimbangkan kode ini:Apakah Anda melihat apa yang salah dengan kode ini? Ada pernyataan pengembalian bersyarat antara
malloc
danfree
. Awalnya mungkin tampak baik-baik saja, tetapi pikirkanlah. Jika ada kesalahan, Anda akan kembali tanpa membebaskan memori yang Anda alokasikan. Ini adalah sumber kebocoran memori yang umum.Tentu saja ini adalah contoh yang sangat sederhana, dan sangat mudah untuk melihat kesalahannya di sini, tetapi bayangkan ratusan baris kode berserakan dengan pointer,
malloc
s,free
s, dan segala macam penanganan kesalahan. Segalanya bisa menjadi sangat berantakan dengan sangat cepat. Ini adalah salah satu alasan saya lebih memilih C ++ modern daripada C dalam kasus yang berlaku, tetapi itu topik yang sama sekali berbeda.Jadi, kapan pun Anda menggunakan
malloc
, selalu pastikan memori Andafree
sedapat mungkin.sumber
ilegal, string literal adalah ilegal
const
.Ini akan mengalokasikan array karakter 12-byte pada stack atau secara global (tergantung di mana ia dideklarasikan).
Jika Anda ingin meninggalkan ruang untuk manipulasi lebih lanjut, Anda dapat menentukan bahwa array harus berukuran lebih besar. (Tolong jangan menaruh 1MB di tumpukan.)
sumber
Salah satu alasan saat perlu mengalokasikan memori adalah jika Anda ingin mengubahnya saat runtime. Dalam hal ini, malloc atau buffer di stack dapat digunakan. Contoh sederhana dari menugaskan "Hello World" ke pointer mendefinisikan memori yang "biasanya" tidak dapat dimodifikasi saat runtime.
sumber