Pemrograman C

malloc dalam bahasa c

malloc dalam bahasa c
Anda dapat datang ke sini karena dua alasan: apakah Anda ingin mengalokasikan konten secara dinamis, atau Anda ingin tahu lebih banyak tentang cara kerja malloc. Bagaimanapun, Anda berada di tempat yang tepat! Alokasi dinamis adalah proses yang sering terjadi tetapi umumnya kami tidak menggunakannya sendiri: sebagian besar bahasa pemrograman mengelola memori untuk Anda karena ini adalah pekerjaan yang sulit dan jika Anda gagal melakukannya dengan benar, ada implikasi keamanan.

Namun, jika Anda melakukan C, C++ atau kode assembly, atau jika Anda menerapkan modul eksternal baru dalam bahasa pemrograman favorit Anda, Anda perlu mengelola sendiri alokasi memori dinamis Anda.

Apa itu alokasi dinamis?? Mengapa saya membutuhkan malloc?

Nah, di semua aplikasi, saat Anda membuat variabel baru - itu sering disebut mendeklarasikan variabel - Anda membutuhkan memori untuk menyimpannya. Karena komputer Anda di zaman modern, ia dapat menjalankan lebih dari satu aplikasi pada satu waktu dan karenanya, setiap aplikasi harus memberi tahu OS Anda (di sini Linux) bahwa itu membutuhkan jumlah memori itu. Saat Anda menulis kode semacam ini:

#termasuk
#termasuk
#define DISK_SPACE_ARRAY_LENGTH 7
void getFreeDiskSpace(int statsList[], size_t listLength)
kembali;

int utama()
/* Berisi ruang disk kosong selama 7 hari terakhir. */
int freeDiskSpace[DISK_SPACE_ARRAY_LENGTH] = 0;
getFreeDiskSpace(freeDiskSpace, DISK_SPACE_ARRAY_LENGTH);
kembali EXIT_SUCCESS;

Array freeDiskSpace membutuhkan memori sehingga Anda harus meminta persetujuan Linux untuk mendapatkan memori. Namun, karena jelas ketika membaca kode sumber bahwa Anda memerlukan array 7 int, kompiler secara otomatis meminta Linux untuk itu, dan itu akan mengalokasikannya di tumpukan. Ini pada dasarnya berarti bahwa penyimpanan ini dihancurkan ketika Anda mengembalikan fungsi di mana variabel dideklarasikan. Itu sebabnya Anda tidak bisa melakukan itu:

#termasuk
#termasuk
#define DISK_SPACE_ARRAY_LENGTH 7
int* getFreeDiskSpace()
int statsList[DISK_SPACE_ARRAY_LENGTH] = 0;
/* KENAPA KITA MELAKUKAN ITU?! statsList akan DIHANCURKAN! */
kembali statsList;

int utama()
/* Berisi ruang disk kosong selama 7 hari terakhir. */
int *freeDiskSpace = NULL;
freeDiskSpace = getFreeDiskSpace();
kembali EXIT_SUCCESS;

Anda lebih mudah melihat masalahnya sekarang? Kemudian, Anda ingin menggabungkan dua string. Dalam Python dan JavaScript, Anda akan melakukan:

newStr = str1 + str2

Tapi seperti yang Anda tahu, di C tidak berfungsi seperti ini. Jadi untuk membangun URL misalnya, Anda perlu menggabungkan dua string, seperti jalur URL dan nama domain. Di C, kami memiliki strcat, benar, tetapi itu hanya berfungsi jika Anda memiliki array dengan ruang yang cukup untuk itu.

Anda akan tergoda untuk mengetahui panjang string baru dengan menggunakan strlen, dan Anda akan benar. Tapi kemudian, bagaimana Anda meminta Linux untuk memesan jumlah memori yang tidak diketahui ini?? Kompiler tidak dapat membantu Anda: ruang persis yang ingin Anda alokasikan hanya diketahui saat runtime. Di situlah Anda membutuhkan alokasi dinamis, dan malloc.

Menulis fungsi C pertama saya menggunakan malloc

Sebelum menulis kode, sedikit penjelasan: malloc memungkinkan Anda mengalokasikan sejumlah byte tertentu untuk penggunaan aplikasi Anda. Ini sangat mudah digunakan: Anda memanggil malloc dengan jumlah byte yang Anda butuhkan, dan itu mengembalikan pointer ke area baru Anda yang disediakan Linux untuk Anda.

Anda hanya memiliki 3 tanggung jawab:

  1. Periksa apakah malloc mengembalikan NULL. Itu terjadi ketika Linux tidak memiliki cukup memori untuk menyediakan.
  2. Bebaskan variabel Anda setelah tidak digunakan. Jika tidak, Anda akan membuang-buang memori dan itu akan memperlambat aplikasi Anda.
  3. Jangan pernah menggunakan zona memori setelah Anda membebaskan variabel.

Jika Anda mengikuti semua aturan ini, semuanya akan berjalan dengan baik dan alokasi dinamis akan menyelesaikan banyak masalah Anda. Karena Anda memilih kapan Anda mengosongkan memori, Anda juga dapat dengan aman mengembalikan variabel yang dialokasikan dengan malloc. Hanya, jangan lupa untuk membebaskannya!

Jika Anda bertanya-tanya bagaimana cara membebaskan variabel, itu dengan fungsi gratis. Sebut saja dengan pointer yang sama dari malloc mengembalikan Anda, dan memori dibebaskan.

Mari saya tunjukkan dengan contoh concat:

#termasuk
#termasuk
#termasuk
/*
* Saat memanggil fungsi ini, jangan lupa untuk memeriksa apakah nilai yang dikembalikan adalah NULL
* Jika bukan NULL, Anda harus memanggil gratis pada pointer yang dikembalikan setelah nilainya
*tidak digunakan lagi.
*/
char* getUrl(const char* const baseUrl, const char* const toolPath)
size_t finalUrlLen = 0;
char* finalUrl = NULL;
/* Pemeriksaan keamanan. */
if (baseUrl == NULL || toolPath == NULL)
kembali NULL;

finalUrlLen = strlen(baseUrl) + strlen(toolPath);
/* Jangan lupa '\0', maka +1. */
finalUrl = malloc(sizeof(char) * (finalUrlLen + 1));
/* Mengikuti aturan malloc… */
if (finalUrl == NULL)
kembali NULL;

strcpy(finalUrl, baseUrl);
strcat(finalUrl, toolPath);
kembali finalUrl;

int utama()
char* googleImages = NULL;
googleImages = getUrl("https://www.google.com", "/imghp");
if (googleImages == NULL)
kembali EXIT_FAILURE;

puts("URL Alat:");
puts(googleImages);
/* Tidak diperlukan lagi, bebaskan. */
gratis(googleImages);
googleImages = NULL;
kembali EXIT_SUCCESS;

Jadi Anda melihat contoh praktis untuk menggunakan alokasi dinamis. Pertama, saya menghindari jebakan seperti memberikan nilai pengembalian getUrl langsung ke fungsi puts. Kemudian, saya juga meluangkan waktu untuk berkomentar dan mendokumentasikan fakta bahwa nilai pengembalian harus dibebaskan dengan benar. Saya juga memeriksa nilai NULL di mana-mana sehingga apa pun yang tidak terduga dapat ditangkap dengan aman alih-alih merusak aplikasi crash.

Akhirnya, saya lebih berhati-hati untuk membebaskan variabel dan kemudian mengatur pointer ke NULL. Itu menghindari tergoda untuk menggunakan - bahkan karena kesalahan - zona memori yang sekarang dibebaskan. Tetapi seperti yang Anda lihat, mudah untuk membebaskan variabel.

Anda mungkin memperhatikan bahwa saya menggunakan sizeof di malloc. Ini memungkinkan untuk mengetahui berapa banyak byte yang digunakan char dan mengklarifikasi maksud dalam kode sehingga lebih mudah dibaca. Untuk char, sizeof(char) selalu sama dengan 1, tetapi jika Anda menggunakan array int, cara kerjanya persis sama. Misalnya, jika Anda perlu memesan 45 int, lakukan saja:

fileSizeList = malloc(sizeof(int) * 45);

Dengan cara ini, Anda dengan cepat melihat berapa banyak yang ingin Anda alokasikan, itu sebabnya saya selalu merekomendasikan penggunaannya.

Bagaimana cara kerja malloc di bawah tenda??

malloc dan gratis, pada kenyataannya, adalah fungsi yang disertakan dalam semua program C yang akan berbicara dengan Linux atas nama Anda. Ini juga akan membuat alokasi dinamis lebih mudah karena, pada awalnya, Linux tidak mengizinkan Anda untuk mengalokasikan variabel dari semua ukuran.

Linux menyediakan dua cara untuk mendapatkan lebih banyak memori sebenarnya: sbrk dan mmap. Keduanya memiliki keterbatasan, dan salah satunya adalah: Anda hanya dapat mengalokasikan jumlah yang relatif besar, seperti 4.096 byte atau 8.192 byte. Anda tidak dapat meminta 50 byte seperti yang saya lakukan pada contoh, tetapi Anda juga tidak dapat meminta 5.894 byte.

Ini memiliki penjelasan: Linux perlu menyimpan tabel di mana ia memberi tahu aplikasi mana yang telah memesan zona memori mana. Dan tabel ini juga menggunakan ruang, jadi jika setiap byte membutuhkan baris baru di tabel ini, akan dibutuhkan sebagian besar memori. Itu sebabnya memori dibagi dalam blok besar, misalnya, 4.096 byte, dan seperti Anda tidak dapat membeli 2 setengah jeruk di toko bahan makanan, Anda tidak dapat meminta setengah blok.

Jadi malloc akan mengambil blok besar ini dan memberi Anda sepotong kecil blok memori ini kapan pun Anda menyebutnya. Juga, jika Anda membebaskan beberapa variabel, tetapi tidak cukup untuk membenarkan pembebasan seluruh blok, sistem malloc dapat menyimpan blok dan mendaur ulang zona memori saat Anda memanggil malloc lagi. Ini memiliki manfaat untuk membuat malloc lebih cepat, namun memori yang dicadangkan oleh malloc tidak dapat digunakan di aplikasi lain, sementara program saat ini tidak menggunakannya dalam kenyataan.

Tapi malloc pintar: jika Anda memanggil malloc untuk mengalokasikan 16 MiB atau jumlah besar, malloc mungkin akan meminta Linux untuk blok penuh yang didedikasikan hanya untuk variabel besar ini dengan menggunakan mmap. Dengan cara ini, ketika Anda menelepon gratis, kemungkinan besar akan menghindari pemborosan ruang itu. Jangan khawatir, malloc melakukan pekerjaan daur ulang yang jauh lebih baik daripada yang dilakukan manusia dengan sampah kita!

Kesimpulan

Saya pikir sekarang Anda lebih memahami bagaimana semua itu bekerja. Tentu saja, alokasi dinamis adalah topik besar dan saya pikir kita dapat menulis buku lengkap tentang topik tersebut, tetapi artikel ini akan membuat Anda nyaman dengan konsep baik secara umum maupun dengan saran pemrograman praktis.

Game Remaster HD untuk Linux yang Belum Pernah Rilis Linux Sebelumnya
Banyak pengembang dan penerbit game datang dengan remaster HD dari game lama untuk memperpanjang umur waralaba, harap penggemar meminta kompatibilitas...
Cara Menggunakan AutoKey untuk Mengotomatiskan Game Linux
AutoKey adalah utilitas otomatisasi desktop untuk Linux dan X11, diprogram dengan Python 3, GTK dan Qt. Dengan menggunakan skrip dan fungsionalitas MA...
Cara Menampilkan Penghitung FPS di Game Linux
Game Linux mendapat dorongan besar ketika Valve mengumumkan dukungan Linux untuk klien Steam dan game mereka pada tahun 2012. Sejak itu, banyak game A...