15. Dinamik xotira¶
Oldingi bo‘limda ma'lumotlarni faylda saqlashni o‘rgandik.
Endi kompyuter xotirasi bilan biroz chuqurroq tanishamiz.
Bu bo‘limda yangi ikkita funksiya bilan tanishamiz:
malloc()
free()
Ular yordamida dastur ishlayotgan vaqtda xotiradan joy ajratishimiz mumkin.
Dinamik xotira nima?¶
Avval massiv yaratganimizda uning o‘lchamini oldindan belgilardik.
Masalan:
int sonlar[5];
Bu yerda 5 ta int uchun joy ajratiladi.
Lekin ba'zida dastur ishlayotgan paytda nechta element kerakligini bilmaymiz.
Masalan, foydalanuvchi:
Nechta son kiritasiz? 100
desa, bizga 100 ta son uchun joy kerak.
Bunday vaziyatda dinamik xotira foydali bo‘ladi.
malloc() nima?¶
malloc() xotiradan kerakli miqdorda joy ajratadi.
U stdlib.h kutubxonasida joylashgan.
Shuning uchun:
#include <stdlib.h>
yozishimiz kerak.
Oddiy misol:
int *p = malloc(sizeof(int));
Bu kod bitta int qiymat uchun xotiradan joy ajratadi.
sizeof() nima?¶
sizeof() ma'lumot turi yoki o‘zgaruvchi xotirada qancha joy egallashini aniqlashga yordam beradi.
Masalan:
sizeof(int)
int uchun kerakli xotira hajmini beradi.
Masalan:
int son;
printf("%zu", sizeof(son));
Natija kompyuterga qarab farq qilishi mumkin.
Ko‘pincha int 4 bayt bo‘ladi, lekin bunga doimo ishonib qolmaslik kerak.
malloc() bilan oddiy misol¶
#include <stdio.h>
#include <stdlib.h>
int main() {
int *p = malloc(sizeof(int));
*p = 50;
printf("%d", *p);
free(p);
return 0;
}
Natija:
50
Bu yerda:
malloc()
xotiradan joy ajratdi.
*p = 50;
shu joyga 50 qiymatini yozdi.
free(p);
esa ajratilgan xotirani qaytardi.
free() nima?¶
Dinamik xotira bilan ishlaganimizdan keyin uni bo‘shatish kerak.
Buning uchun:
free(p);
ishlatiladi.
Masalan:
int *p = malloc(sizeof(int));
*p = 100;
printf("%d", *p);
free(p);
free() ishlatilgandan keyin shu xotiradan foydalanmaslik kerak.
Dinamik massiv¶
malloc() yordamida massiv uchun ham xotira ajratish mumkin.
Masalan, 5 ta int uchun:
int *sonlar = malloc(5 * sizeof(int));
Endi sonlar orqali 5 ta int bilan ishlashimiz mumkin.
Masalan:
sonlar[0] = 10;
sonlar[1] = 20;
sonlar[2] = 30;
sonlar[3] = 40;
sonlar[4] = 50;
Dinamik massivni chiqarish¶
To‘liq misol:
#include <stdio.h>
#include <stdlib.h>
int main() {
int *sonlar = malloc(5 * sizeof(int));
sonlar[0] = 10;
sonlar[1] = 20;
sonlar[2] = 30;
sonlar[3] = 40;
sonlar[4] = 50;
for (int i = 0; i < 5; i++) {
printf("%d\n", sonlar[i]);
}
free(sonlar);
return 0;
}
Natija:
10
20
30
40
50
Foydalanuvchi belgilagan hajm¶
Dinamik xotiraning eng katta foydalaridan biri — hajmni dastur ishlayotgan paytda belgilash.
Masalan:
#include <stdio.h>
#include <stdlib.h>
int main() {
int n;
printf("Nechta son kerak? ");
scanf("%d", &n);
int *sonlar = malloc(n * sizeof(int));
for (int i = 0; i < n; i++) {
sonlar[i] = i + 1;
}
for (int i = 0; i < n; i++) {
printf("%d ", sonlar[i]);
}
free(sonlar);
return 0;
}
Agar foydalanuvchi:
5
kiritsa:
1 2 3 4 5
chiqadi.
Agar:
10
kiritsa:
1 2 3 4 5 6 7 8 9 10
chiqadi.
malloc() xatoligini tekshirish¶
Ba'zida xotiradan kerakli joyni ajratib bo‘lmasligi mumkin.
Shuning uchun malloc() natijasini tekshirish yaxshi odat.
Masalan:
int *sonlar = malloc(5 * sizeof(int));
if (sonlar == NULL) {
printf("Xotiradan joy ajratib bo'lmadi.");
return 1;
}
Agar malloc() NULL qaytarsa, xotiradan joy ajratilmagan bo‘ladi.
calloc()¶
C tilida dinamik xotira ajratish uchun calloc() funksiyasi ham mavjud.
Masalan:
int *sonlar = calloc(5, sizeof(int));
Bu 5 ta int uchun joy ajratadi.
calloc() ajratilgan xotirani nol qiymatlar bilan boshlaydi.
Masalan:
sonlar[0] → 0
sonlar[1] → 0
sonlar[2] → 0
sonlar[3] → 0
sonlar[4] → 0
Keyin:
free(sonlar);
bilan xotirani bo‘shatamiz.
Hozircha malloc() va free() ni yaxshi tushunish kifoya.
realloc()¶
Ba'zida ajratilgan xotira hajmini o‘zgartirish kerak bo‘ladi.
Buning uchun realloc() ishlatiladi.
Masalan:
int *sonlar = malloc(5 * sizeof(int));
Keyin 10 ta element kerak bo‘lib qolsa:
sonlar = realloc(sonlar, 10 * sizeof(int));
Shunda ajratilgan xotira hajmini o‘zgartirishga harakat qilinadi.
realloc() biroz murakkabroq bo‘lgani uchun hozircha uning asosiy vazifasini bilish kifoya.
Oddiy hayotiy misol¶
Dinamik xotirani oddiy qilib shunday tasavvur qilish mumkin.
Sizga xona kerak.
Oldindan:
"Menga 5 ta odam uchun xona kerak."
deb xona olishingiz mumkin.
Bu oddiy massivga o‘xshaydi:
int odamlar[5];
Lekin odamlar soni noma'lum bo‘lsa:
"Odamlar kelganda, kerakli kattalikdagi joy ajrataman."
deysiz.
Bu dinamik xotiraga o‘xshaydi.
Dinamik xotirada eng muhim qoida¶
Agar:
malloc()
yoki:
calloc()
orqali xotira ajratsangiz, ish tugagach uni:
free()
bilan bo‘shating.
Masalan:
int *p = malloc(sizeof(int));
*p = 10;
printf("%d", *p);
free(p);
Xotirani ikki marta bo‘shatish mumkin emas¶
Masalan:
free(p);
free(p);
bunday qilish noto‘g‘ri.
free() dan keyin pointerdan yana foydalanish ham noto‘g‘ri.
Masalan:
free(p);
*p = 20;
bunday koddan foydalanmang.
Amaliy mashqlar¶
1-mashq¶
malloc() yordamida bitta int uchun xotira ajrating.
Unga:
100
qiymatini yozing va ekranga chiqaring.
2-mashq¶
malloc() yordamida 5 ta int uchun xotira ajrating.
Quyidagi sonlarni saqlang:
10
20
30
40
50
Keyin for yordamida chiqaring.
3-mashq¶
Foydalanuvchidan n sonini oling.
Keyin n ta int uchun dinamik xotira ajrating.
Masalan:
Nechta son? 4
va massivda:
1
2
3
4
sonlarini saqlang.
4-mashq¶
malloc() ishlatilgandan keyin free() dan foydalaning.
Dasturingizda ajratilgan xotira bo‘shatilganiga ishonch hosil qiling.
5-mashq¶
Quyidagi kodni tushuntirishga harakat qiling:
int *p = malloc(sizeof(int));
*p = 25;
printf("%d", *p);
free(p);
Har bir qator nima qilayotganini o‘zingiz tushuntirib ko‘ring.
Muhim narsalarni eslab qoling¶
Dinamik xotira uchun:
#include <stdlib.h>
Xotiradan joy ajratish:
malloc()
Xotirani bo‘shatish:
free()
Bir nechta element uchun:
malloc(n * sizeof(int))
Masalan:
int *sonlar = malloc(5 * sizeof(int));
Ish tugagach:
free(sonlar);
malloc() natijasini tekshirish:
if (sonlar == NULL) {
printf("Xotiradan joy ajratib bo'lmadi.");
}
Xulosa¶
Dinamik xotira dastur ishlayotgan vaqtda kerakli miqdorda xotira ajratish imkonini beradi.
Asosiy funksiyalar:
malloc()
calloc()
realloc()
free()
Hozircha eng muhim ikkitasi:
malloc() → xotiradan joy ajratadi
free() → ajratilgan xotirani bo‘shatadi