Pengurusan Memori dalam C

Hai sana, para ahli kod masa depan! Hari ini, kita akan melihat dunia yang menarik pengurusan memori dalam C. Jangan bimbang jika anda baru dalam programming; saya akan menggapai anda melalui perjalanan ini langkah demi langkah, seperti yang saya lakukan untuk pelajar-pelajar yang tak terhitung jumlahnya sepanjang tahun pengajaran saya. Jadi, ambil topi keras maya anda, dan mari kita jelajah kawasan pembinaan memori komputer!

C - Memory Management

Fungsi untuk Pengurusan Memori Dinamik dalam C

Sebelum kita mula membina menara memori kita, mari kita familiar dengan alat yang akan kita gunakan. Dalam C, kita ada set fungsi yang membantu kita menguruskan memori secara dinamik. Anggap fungsi-fungsi ini sebagai beg alatmu yang boleh dipercayai:

Fungsi Tujuan
malloc() Mengalokasikan blok memori
calloc() Mengalokasikan dan menginitialkan beberapa blok memori
realloc() Mengubah saiz blok memori yang sebelum ini dialokasikan
free() Melepaskan memori dialokasikan kembali ke sistem

Fungsi-fungsi ini seperti krew pembinaan bangunan memori kita. Setiap daripadanya mempunyai kerja khasnya sendiri, dan kita akan mengenalpasti mereka semua secara intim.

Mengalokasikan Memori Secara Dinamik

Bayangkan anda merancang sebuah pesta, tetapi anda tidak pasti berapa ramai tetamu yang akan datang. Itu di mana pengalokasian memori dinamik menjadi berguna! Sebaliknya menetapkan jumlah kerusi tetap, anda boleh menambah atau menghapuskan mereka seperti yang diperlukan. Mari kita lihat bagaimana kita melakukan ini dalam C.

Fungsi malloc()

Superhero pengalokasian memori pertama kita adalah malloc(). Ia berarti "pengalokasian memori" dan digunakan untuk meminta blok memori dari sistem.

#include <stdio.h>
#include <stdlib.h>

int main() {
int *numbers;
int size = 5;

numbers = (int*)malloc(size * sizeof(int));

if (numbers == NULL) {
printf("Pengalokasian memori gagal!\n");
return 1;
}

for (int i = 0; i < size; i++) {
numbers[i] = i * 10;
printf("numbers[%d] = %d\n", i, numbers[i]);
}

free(numbers);
return 0;
}

mari kita pecahkan ini:

  1. Kita termasukkan <stdlib.h> kerana itu di mana malloc() tinggal.
  2. Kita deklarasikan pointer numbers untuk menyimpan array yang dialokasikan secara dinamik.
  3. malloc(size * sizeof(int)) meminta cukup memori untuk menyimpan 5 integer.
  4. Kita casting hasilnya ke (int*) kerana malloc() mengembalikan pointer void.
  5. Selalu periksa jika malloc() berjaya! Jika ia mengembalikan NULL, kita tidak beruntung (dan tanpa memori).
  6. Kita sekarang boleh menggunakan numbers seperti array biasa.
  7. Jangan lupa untuk free() memori saat Anda selesai!

Fungsi calloc()

Sekarang, temui calloc(), obsesif bersih dalam pengalokasian memori. Sementara malloc() memberikan anda memori dengan apa pun yang di situ sebelumnya, calloc() membersihkan dirinya sendiri, menginitialkan semua memori dialokasikan ke nol.

#include <stdio.h>
#include <stdlib.h>

int main() {
int *numbers;
int size = 5;

numbers = (int*)calloc(size, sizeof(int));

if (numbers == NULL) {
printf("Pengalokasian memori gagal!\n");
return 1;
}

for (int i = 0; i < size; i++) {
printf("numbers[%d] = %d\n", i, numbers[i]);
}

free(numbers);
return 0;
}

Perbezaan utama di sini:

  1. calloc() mengambil dua argumen: bilangan elemen dan saiz setiap elemen.
  2. Semua elemen diinitialkan ke nol, jadi output kita akan semua nol.

Mengubah Saiz dan Melepaskan Memori

Kadang-kadang, pesta kita menjadi lebih besar atau lebih kecil daripada yang dijangka. Itu di mana realloc() menjadi berguna!

Fungsi realloc()

realloc() seperti seorang ahli magik yang dapat memperluas atau menyusut blok memori kita.

#include <stdio.h>
#include <stdlib.h>

int main() {
int *numbers;
int size = 5;

numbers = (int*)malloc(size * sizeof(int));

if (numbers == NULL) {
printf("Pengalokasian memori gagal!\n");
return 1;
}

for (int i = 0; i < size; i++) {
numbers[i] = i * 10;
printf("numbers[%d] = %d\n", i, numbers[i]);
}

// Mari kita perluaskan array kita
size = 10;
numbers = (int*)realloc(numbers, size * sizeof(int));

if (numbers == NULL) {
printf("Pengalokasian memori gagal!\n");
return 1;
}

// Isi elemen baru
for (int i = 5; i < size; i++) {
numbers[i] = i * 10;
}

// Cetak semua elemen
for (int i = 0; i < size; i++) {
printf("numbers[%d] = %d\n", i, numbers[i]);
}

free(numbers);
return 0;
}

Ini adalah apa yang berlaku:

  1. Kita mulai dengan 5 elemen, seperti sebelumnya.
  2. Kita gunakan realloc() untuk memperluas array kita ke 10 elemen.
  3. realloc() mempertahankan data asal kita dan memberikan kita ruang lebih.
  4. Kita isi elemen baru dan cetak semua itu.

Fungsi free()

Last but not least, kita ada free(), krew pembersihan pengurusan memori kita. Sentiasa ingat untuk free() memori yang anda alokasi saat anda selesai dengannya!

#include <stdio.h>
#include <stdlib.h>

int main() {
int *numbers = (int*)malloc(5 * sizeof(int));

if (numbers == NULL) {
printf("Pengalokasian memori gagal!\n");
return 1;
}

for (int i = 0; i < 5; i++) {
numbers[i] = i * 10;
printf("numbers[%d] = %d\n", i, numbers[i]);
}

free(numbers);  // Bersihkan!
numbers = NULL; // Praktik baik untuk menghindari penggunaan memori yang dilepaskan

// Mencoba menggunakan 'numbers' sekarang akan menjadi ide yang buruk!

return 0;
}

Ingat:

  1. Selalu free() memori yang anda alokasi saat anda selesai dengannya.
  2. Set pointer ke NULL setelah melepaskan untuk menghindari penggunaan memori yang dilepaskan secara tidak sengaja.
  3. Jangan pernah mencoba free() memori yang anda tidak alokasi secara dinamik.

Dan itu lah, teman-teman! Kita telah membina menara pengurusan memori kita, belajar bagaimana mengalokasikan ruang untuk tetamu pesta kita, mengatur tempat saat diperlukan, dan membersihkan kemudian. Ingat, pengurusan memori yang baik adalah seperti menjadi tuan rumah yang baik - selalu pastikan anda memiliki cukup ruang untuk tetamu anda, fleksibel dengan peraturan anda, dan bersih sepenuhnya saat pesta selesai!

Terus latih konsep ini, dan segera anda akan menjadi arsitek pengurusan memori program anda. Selamat coding, dan mayat program anda selalu berjalan tanpa kebocoran memori!

Credits: Image by storyset