* Функции за разпределение на паметта
Публикувано на 26 октомври 2008 в раздел С/С++.
Всеки компютър разполага с определено количество свободна памет. За да се използува ефективно тя трябва да се разпределя динамично. В С имаме възможност да променяме подразбиращият се размер на стека по време на изполнението на програмата. Програмистът обаче сам трябва да се грижи да предпазва стека от препълване.
Ще разгледаме две от функциите за разпределение на паметта от високо ниво - malloc, calloc и free.
1. malloc: Резервира блок памет и връща указател към блока:
int *p = (int *)malloc(unsigned bytes);
Чрез bytes указваме точно колко байта памет искаме да резервираме. Ако няма достатъчно памет в указателя p ще се запише NULL. Имайте предвид, че ако се опитате да записвате информация чрез такъв указател програмата ще завърше с фатална грешка, затова винаги проверявайте резултатът от malloc!
2. calloc: Резервира блок памет и нулира всичките му байтове:
int *p = (int *)calloc(unsigned number, unsigned elnumber);
Number e броя елементи, за които се заделя памет, а elnumber е типа данни на тези елементи. Например:
// Заделя и нулира памет за 10 елемента от тип float int *p = (int *)calloc(10, sizeof(float));
3. free: Овобождава блока памет заделен чрез malloc или calloc:
free(int *p);
Пример: Реализираме стек с използване на указатели, като предварително заделяме памет за него:
#include "stdafx.h" #include "stdio.h" #include "stdlib.h" #define STACKSIZE 5 // Ukazatel kam chisloto i int *pi; // Nachalo na steka int *pimin; // vkarvane na element v steka void push(){ if (pi == pimin + STACKSIZE){ printf("Stack is full! Please pop some elements\n\n"); return; } else{ int num; printf("Enter number to push in stack: "); scanf("%d", &num); *pi = num; pi++; return; } } // premahvane na element ot steka void pop(){ if (pi == pimin){ printf("Stack is empty!\n\n"); return; } else{ pi--; printf("Last element in stack: %d\n\n", *pi); return; } } int main(int argc, char* argv[]) { // Zadeliame pamet za STACKSIZE na broi elementa s razmer int pimin = (int *)calloc(STACKSIZE, sizeof(int)); pi = pimin; int action; do{ printf("1. Push number to stack\n"); printf("2. Pop number to stack\n"); printf("3. Exit\n\n"); printf("Choose action: "); scanf("%d", &action); switch(action){ case 1: push(); break; case 2: pop(); break; case 3: break; default: printf("invalid option\n\n\n"); break; } } while(action != 3); free(pimin); return 0; }
Задача: Приложете техниката описана в статията Проблеми свързани с използването на scanf в горния пример.
Били са 20, станали са 5, а грешката в коментара си е останала. Ще редактирам. Благодаря за забележката.
"// Osvobojdavame pamet za 20 elementa s razmer int
pimin = (int *)calloc(STACKSIZE, sizeof(int));"
Как да са 20 елемента, като сте дефинирали STACKSIZE = 5?
"#define STACKSIZE 5"
// Zadeliame pamet za STACKSIZE na broi elementa s razmer int
pimin = (int *)calloc(STACKSIZE, sizeof(int));
Брой елемента с размер int или oт тип int?
Размерът на тип int. Нищо не ти пречи да запишеш и друг тип данни там (но не е проява на добра практика).