C xotira misoli


ULASHISH

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 myList strukturasi
  • 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‘rsatkich
  • numItems - ro‘yxatdagi elementlar sonini bildiradi
  • size - 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)
  1. Ro‘yxatga ko‘rsatkich.
  2. 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!