C xotira misoli
Xotirani boshqarishga oid hayotiy misol
Dinamik xotiraning amaliy misolini ko‘rsatish uchun istalgan uzunlikdagi ro‘yxat tuza oladigan dastur yaratdik.
C tilidagi oddiy massivlar qat’iy uzunlikka ega va uni o‘zgartirib bo‘lmaydi, lekin dinamik xotira yordamida xohlagancha uzun ro‘yxat yaratishimiz mumkin:
Misol
struct list {
int *data; // Points to the memory where the list items are stored
int numItems; // Indicates how many items are currently in the list
int size; // Indicates how many items fit in the allocated memory
};
void addToList(struct list *myList, int item);
int main() {
struct list myList;
int amount;
int i, j;
// Create a list and start with enough space for 10 items
myList.numItems = 0;
myList.size = 10;
myList.data = malloc(myList.size * sizeof(int));
// Find out if memory allocation was successful
if (myList.data == NULL) {
printf("Memory allocation failed");
return 1; // Exit the program with an error code
}
// Add any number of items to the list specified by the amount variable
amount = 44;
for (i = 0; i < amount; i++) {
addToList(&myList, i + 1);
}
// Display the contents of the list
for (j = 0; j < myList.numItems; j++) {
printf("%d ", myList.data[j]);
}
// Free the memory when it is no longer needed
free(myList.data);
myList.data = NULL;
return 0;
}
// This function adds an item to a list
void addToList(struct list *myList, int item) {
// If the list is full then resize the memory to fit 10 more items
if (myList->numItems == myList->size) {
int newSize = myList->size + 10;
// Use a temporary pointer so we don't lose the original on failure
int *tmp = realloc(myList->data, newSize * sizeof(int));
if (tmp == NULL) {
printf("Memory resize failed\n");
return; // Leave the list unchanged
}
// Only update fields after a successful reallocation
myList->data = tmp;
myList->size = newSize;
}
// Add the item to the end of the list
myList->data[myList->numItems] = item;
myList->numItems++;
}
O‘zingiz sinab ko‘ring »
Strukturalarga ko‘rsatkichlar: Bu misolda myList strukturasiga ko‘rsatkich bor. Strukturaning o‘zi o‘rniga unga ko‘rsatkichdan foydalanayotganimiz uchun struktura a’zolariga murojaat qilishda strelka sintaksisidan (->) foydalanamiz.
Misol izohi
Bu misol uch qismdan iborat:
- Ro‘yxat ma’lumotlarini o‘z ichiga olgan
myListstrukturasi - Dasturni o‘z ichiga olgan
main()funksiyasi. - Ro‘yxatga element qo‘shadigan
addToList()funksiyasi
myList strukturasi
myList strukturasi ro‘yxat haqidagi barcha ma’lumotlarni, jumladan uning tarkibini ham saqlaydi. Uning uchta a’zosi bor:
data- ro‘yxat tarkibini saqlaydigan dinamik xotiraga ko‘rsatkichnumItems- ro‘yxatdagi elementlar sonini bildiradisize- ajratilgan xotiraga nechta element sig‘ishini bildiradi
Bu ma’lumotlarning barchasini funksiyaga osongina uzatish uchun strukturadan foydalanamiz.
main() funksiyasi
main() funksiyasi ishni ro‘yxatni 10 ta element uchun joy bilan initsializatsiya qilishdan boshlaydi:
// Create a list and start with enough space for 10 items
myList.numItems = 0;
myList.size = 10;
myList.data = malloc(myList.size * sizeof(int));
myList.numItems qiymati 0 ga tenglanadi, chunki ro‘yxat dastlab bo‘sh bo‘ladi.
myList.size qancha xotira band qilinganini kuzatib boradi. Unga 10 qiymatini beramiz, chunki 10 ta element uchun yetarli xotira band qilamiz.
So‘ngra xotira ajratamiz va unga ko‘rsatkichni myList.data a’zosida saqlaymiz.
Keyin xotira ajratish muvaffaqiyatli bo‘lganini bilish uchun xatolarni tekshirishni qo‘shamiz:
// Find out if memory allocation was successful
if (myList.data == NULL) {
printf("Memory allocation failed");
return 1; // Exit the program with an error code
}
Agar hammasi joyida bo‘lsa, sikl addToList() funksiyasi yordamida ro‘yxatga 44 ta element qo‘shadi:
// Add any number of items to the list specified by the amount variable
amount = 44;
for (i = 0; i < amount; i++) {
addToList(&myList, i + 1);
}
Yuqoridagi kodda &myList — ro‘yxatga ko‘rsatkich, i + 1 esa ro‘yxatga qo‘shmoqchi bo‘lgan sonimiz. Ro‘yxat 0 dan emas, 1 dan boshlanishi uchun i + 1 ifodasini tanladik. Ro‘yxatga qo‘shish uchun istalgan sonni tanlashingiz mumkin.
Barcha elementlar ro‘yxatga qo‘shilgach, keyingi sikl ro‘yxat tarkibini chiqaradi.
// Display the contents of the list
for (j = 0; j < myList.numItems; j++) {
printf("%d ", myList.data[j]);
}
Ro‘yxatni chiqarib bo‘lgach, xotira sizib chiqishining oldini olish uchun xotirani bo‘shatamiz.
// Free the memory when it is no longer needed
free(myList.data);
myList.data = NULL;
addToList() funksiyasi
Bizning addToList() funksiyamiz ro‘yxatga element qo‘shadi. U ikkita parametr qabul qiladi:
void addToList(struct list *myList, int item)
- Ro‘yxatga ko‘rsatkich.
- Ro‘yxatga qo‘shiladigan qiymat.
Funksiya avval ro‘yxatdagi elementlar sonini o‘lcham (sig‘im) bilan solishtirib, ro‘yxat to‘lganini tekshiradi. Agar ro‘yxat to‘lgan bo‘lsa, u yana 10 ta element sig‘ishi uchun xotirani kengaytirishga harakat qiladi. O‘lchamni o‘zgartirish muvaffaqiyatsiz bo‘lsa, asl blokni yo‘qotmaslik uchun realloc bilan vaqtinchalik ko‘rsatkichdan foydalanamiz. data va size a’zolarini faqat o‘lcham muvaffaqiyatli o‘zgartirilgandan keyin yangilaymiz:
// If the list is full then resize the memory to fit 10 more items
if (myList->numItems == myList->size) {
int newSize = myList->size + 10;
// Use a temp pointer so we don't lose the original on failure
int *tmp = realloc(myList->data, newSize * sizeof(int));
if (tmp == NULL) {
printf("Memory resize failed\n");
return; // Leave the list unchanged
}
// Only update fields after a successful reallocation
myList->data = tmp;
myList->size = newSize;
}
Nihoyat, funksiya elementni ro‘yxat oxiriga qo‘shadi. myList->numItems indeksi har doim ro‘yxat oxirida bo‘ladi, chunki har safar yangi element qo‘shilganda u 1 ga ortadi:
// Add the item to the end of the list
myList->data[myList->numItems] = item;
myList->numItems++;
Nima uchun bir yo‘la 10 ta element uchun joy band qilamiz?
Optimallashtirish — xotira va unumdorlik o‘rtasidagi muvozanatni saqlash demakdir. Garchi foydalanmaydigan xotiraning bir qismini ajratayotgan bo‘lsak-da, xotirani juda tez-tez qayta ajratish samarasiz bo‘lishi mumkin. Juda ko‘p xotira ajratish bilan xotirani juda tez-tez ajratish o‘rtasida muvozanat topish kerak.
Bu misol uchun 10 sonini tanladik, lekin bu siz qancha ma’lumot kutayotganingiz va u qanchalik tez-tez o‘zgarishiga bog‘liq. Masalan, aynan 44 ta element bo‘lishini oldindan bilsak, aynan 44 ta element uchun xotirani faqat bir marta ajratishimiz mumkin.
To‘liq stdlib ma’lumotnomasi
Xotirani boshqarish funksiyalari va standart kutubxonadagi boshqa funksiyalarning to‘liq ro‘yxati uchun C <stdlib.h> kutubxonasi ma’lumotnomasiga o‘ting.
W3Schools Pathfinder
Yutuqlaringizni kuzating – bu bepul!
