Динамические объекты

До сих пор для всех объектов, рассматриваемых в пособии, память выделялась по информации программы автоматически. Для объектов класса памяти static и extern во время трансляции в статической области, для объектов класса памяти auto и register динамически (во время выполнения) в области, называемой программным стеком. Однако, в языке C, как и во многих других языках программирования, имеется возможность выделять память под программные объекты прямым указанием программиста. Такие объекты располагаются в отдельной области – куче (heap). Их принято называть динамическими.

Для этих целей в библиотеки языка Cвключены функции malloc, calloc и free. Их прототипы хранятся в файле alloc.h.

Выделение памяти.

void* malloc(unsigned size); // Размер в байтах

void* calloc(unsigned kol, // Число элементов

unsigned size); // Размер в байтах

Освобождение памяти: void free(void *ptr);

Если памяти не хватает, то функции возвращают значение NULL. Освободить память в куче можно только функцией free.

Как видно из прототипов, объекты в этой области имен не имеют и работа с ними выполняются исключительно с помощью указателей. Часто говорят, что куча - это неименованная область памяти. Для того, чтобы сделать программу независимой от компьютера и операционной системы, при выделении памяти используют оператор sizeof(<тип>).

Пример.

sizeof(short) à 2 байта

sizeof(DATA) à размер определяется по инструкции typedef.

Функции malloc и calloc возвращают указатель на void, который не может использоваться для ссылки на объект, поэтому при размещении объектов в куче программист обязан задать тип размещаемого объекта с помощью оператора приведения типа.

Пример. Динамическое выделение памяти под массив заданного размера n. p=(char*)malloc(n*sizeof(char)); p=(char*)calloc(n, sizeof(char));

Примеры. Манипуляции с массивом произвольного размера.

float *ptr, buf;

short i, n;

........................................

printf("Длина массива:");

scanf("%d", &n);

/* Выделить память под массив */

ptr=(float*)calloc(n, sizeof(float));

/* Ввести массив */

printf("Исходный массив\n");

for(i=0; i<n; i++){

scanf("%f", &buf); *(ptr + i ) = buf; /* ptr[ i ] = buf; */

}

.................................

free(ptr);

2. Функция substr – аналог функции mid языка Basic.

#include <string.h>

#include <alloc.h>

/* Выделить из строки s подстроку длиной length с позиции begin */

/* Если length == 0, выделяется подстрока с begin до конца s */

char* substr(const char *s, short begin, shortlength){

char* p; / Подстрока */

short i;

if(length == 0) length = strlen(s) – begin + 1; // До конца строки s

/* Обработка ошибки */

if(begin < 1 || length < 1 || begin + length – 1 > strlen(s))return NULL;

p=(char*)calloc(length + 1, sizeof(char));

for(i=0; i < length; i++){

*(p + i) = *(s + begin + i - 1);

}

*(p + i) = '\0';

return p;

} /* End substr */

Замечание. В функции память выделяется, но не освобождается, поэтому после того, как необходимость в выделенной памяти отпадет, ее следует освободить функцией free(p).