C, PHP, VB, .NET

Дневникът на Филип Петров


* Функции за разпределение на паметта

Публикувано на 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 в горния пример.

 



4 коментара


  1. Били са 20, станали са 5, а грешката в коментара си е останала. Ще редактирам. Благодаря за забележката.

  2. Франсоа каза:

    „// Osvobojdavame pamet za 20 elementa s razmer int
    pimin = (int *)calloc(STACKSIZE, sizeof(int));“

    Как да са 20 елемента, като сте дефинирали STACKSIZE = 5?

    „#define STACKSIZE 5“

  3. Франсоа каза:

    // Zadeliame pamet za STACKSIZE na broi elementa s razmer int
    pimin = (int *)calloc(STACKSIZE, sizeof(int));

    Брой елемента с размер int или oт тип int?

  4. Размерът на тип int. Нищо не ти пречи да запишеш и друг тип данни там (но не е проява на добра практика).

Добави коментар

Адресът на електронната поща няма да се публикува


*