Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Основы алгоритмизации и программирования .Язык си.pdf
Скачиваний:
104
Добавлен:
16.03.2016
Размер:
4.49 Mб
Скачать

10.8. Работа с динамической памятью

Указатели чаще всего используют при работе с динамической памятью, которую иногда называют «куча» (перевод английского слова heap). Это свободная память, в которой можно во время выполнения программы выделять место в соответствии с потребностями. Доступ к выделенным участкам динамической памяти производится только через указатели. Время жизни динамических объектов – от точки создания до конца программы или

до явного освобождения памяти.

Р

 

С другой стороны, некоторые задачи исключают использование

 

И

структур данных фиксированного размера и требуют введения структур динамических, способных увеличивать или уменьшать свой размер уже в

 

У

процессе работы программы. Основу таких структур составляют

динамические переменные.

 

Динамическая переменная хранится в некоторой области ОП, не

обозначенной именем, и обращение к ней производится через переменную-

указатель.

 

 

Б

Но вначале рассмотрим еще одну операциюГязыка Си, основное

назначение которой – работа с участками оперативной памяти.

10.9. Библиотечные функции

 

е

 

Функции для манипулирования динамической памятью в стандарте Си

следующие:

т

к

 

void *calloc(unsigned

n, unsigned size); – выделение памяти для

размещения n объектов размером size байт и заполнение полученной области

 

 

 

 

 

о

нулями; возвращает указа ель на выделенную область памяти;

 

void

 

 

и

 

*malloc (unsigned n) – выделение области памяти для размещения

блока размером

n байт; в звращает указатель на выделенную область

памяти;

 

ло

 

 

 

 

 

 

void *realloc (void *b, unsigned n) – изменение размера размещенного по

адресу b

б

 

 

лока на новое значение n и копирование (при необходимости)

соде

ржи

 

ка; возвращает указатель на перераспределенную область

мого

 

памяти; при возникновении ошибки, например, нехватке памяти, эти

функц

возвращают

значение NULL, что означает отсутствие адреса

(нулевой адрес);

 

coreleft (void) – получение размера свободной памяти в байтах только

дляБMS DOS (используется в Borland C++), тип результата: unsigned – для

моделей памяти tiny, small и medium; unsigned long – для моделей памяти

compact, large и huge;

 

void

free (void

*b) – освобождение блока памяти, адресуемого

указателем b.

 

Для использования этих функций требуется подключить к программе в

зависимости от среды программирования заголовочный файл alloc.h или malloc.h.

81

__________________________________________________________________

В языке С++ введены операции захвата и освобождения памяти new и delete, рассматриваемые в разд. 16.4.

__________________________________________________________________

10.10.Пример создания одномерного динамического массива

Вязыке Си размерность массива при объявлении должна задаваться

константным выражением.

Если до выполнения программы неизвестно, сколько понадобитсяР элементов массива, нужно использовать динамические массивы, т.е. при необходимости работы с массивами переменной размерностиИвместо массива достаточно объявить указатель требуемого типа и присвоить ему адрес свободной области памяти (захватить память). У

Память под такие массивы выделяется с помощьюГфункций mallос и calloc (операцией new) во время выполнения программы. Адрес начала массива хранится в переменной-указателе. НапримерБ:

В примере значение переменной n

з д но, но может быть

получено и

программным путем.

е

а

 

 

 

Обнуления

памяти

выделении не

происходит.

при

Инициализировать динамический массивкпри декларации нельзя.

 

 

ту

 

 

Обращение к элемен

динамич ского массива осуществляется так же,

как и к элементу обыч го – например а[3]. Можно обратиться к элементу

 

 

но

массива и через косвен ую адресацию – *(а + 3). В любом случае происходят

 

и

те же действия, к т рые выполняются при обращении к элементу массива,

декларированного бычным бразом.

л

 

Пос е работы захваченную под динамический массив память

б

 

 

необходимо освобод ть, для нашего примера free(b);

Таким о разом, время жизни динамического массива, как и любой динамической переменной – с момента выделения памяти до момента ее освобожден я. Область действия элементов массива зависит от места Бдекларац указателя, через который производится работа с его элементами. Область действия и время жизни указателей подчиняются общим правилам для остальных объектов программы.

Пример работы с динамическим массивом:

#include <alloc.h> void main()

{

double *x; int n;

printf("\nВведите размер массива – ");

82

scanf("%d", &n);
if ((x = (double*)calloc(n, sizeof(*x)))==NULL) { puts("Ошибка ");
return;

// Захват памяти

}

 

 

 

 

...

 

 

 

 

// Работа с элементами массива

 

 

 

 

...

 

 

 

 

free(x);

// Освобождение памяти

}

 

 

 

Р

 

 

 

 

__________________________________________________________________

Примеры создания одномерного и двухмерного динамических

 

Г

И

массивов с использованием операций new и delete можно посмотреть в разд.

16.4.

Б

У

 

 

 

__________________________________________________________________

10.11. Пример создания двухмерногоквадин мического массива

Напомним, что ID двухмерного масси – указатель на указатель. На рис. 10.1 приведена схема располож ния элементов, причем в данном случае

сначала выделяется память на указат ли, расположенные последовательно

друг за другом, а затем каждомуеиз них выделяется соответствующий

участок памяти под элемен ы.

 

 

. . .

и

т

 

int **m, n1, n2, i, j;

 

 

 

л

 

 

puts(" Введ те размерыомассива (строк, столбцов): ");

scanf(“%d%d”, &n1, &n2);

 

// Захват памяти д я указателей – А (n1=3)

 

и

 

 

 

 

m = (int**)calloc(n1, sizeof(int*));

 

for (i=0; i<n1; i++)

// Захват памяти для элементов – B (n2=4)

Б

б*(m+i) = (int*)calloc(n2, sizeof(int));

 

for ( i=0; i<n1; i++)

 

 

 

for ( j=0; j<n2; j++)

 

 

. . .

m[i] [j] = i+j;

// *(*(m+i)+j) = i+j;

 

 

 

 

for(i=0; i<n; i++) free(m[i]);

// Освобождение памяти

free(m);

 

 

 

 

 

. . .

 

 

 

83