Определение размера выделяемой памяти (операция sizeof)
Выделение памяти и управление ею
С помощью этой операции можно определить в байтах размер памяти, которая соответствует идентификатору или типу. Выражение с операцией sizeof имеет следующий формат
sizeof (выражение)
Выражение - это либо идентификатор, либо имя типа, заключенное в круглые скобки:
sizeof (имя_объекта) ;
Идентификатор не может относиться к полю битов или быть именем функции.
Если имя типа описывает массив, то результатом является размер всего массива, а не размер указателя, состветствующий имени массива.
Пример 7.1:
# include <stdio. h>
# include <conio. h>
void main (void)
{
float mas[100];
clrscr();
printf( “Размер одного элемента массива %d в байтах\n, sizeof ( mas[20]));
printf( “Размер всего массива %d в байтах\n, sizeof ( mas));
getch();
}
Результат выполнения программы:
Размер одного элемента массива 4 байта.
Размер всего массива 400 байт.
Язык Си позволяет выделять память динамически, т.е. во время работы программы. Как было показано ранее, по области видимости переменные могут быть глобальными и локальными. Для глобальных переменных отводится фиксированная часть памяти на все время работы программы. Локальные переменные хранятся в стеке. Между ними находится область свободной памяти для динамического распределения во время работы программы. Принятое распределение памяти в программах на языке Си показано на рис.7.1.
______________________
| |
Область стека старшие адреса
(заполнять сверху вниз)
_______________________
| |
Свободная область
памяти
_______________________
| Раздел глобальных |
переменных и
констант
_______________________
| |
Область программного
кода младшие адреса
|_______________________|
Рис.7.1
Наиболее важными функциями для динамического распределения памяти являются malloc() и free(). Прототипы этих функций хранятся в заголовочном файле alloc.h
Выделение памяти размером size байт осуществляется функцией malloc() .
Синтаксис использования:
unsigned size; / * размер блока памяти в байтах */
void *malloc (size) ;
void free(void *p);
Функция malloc() возвращает указатель на первый байт выделенного блока памяти либо NULL, если для выделения памяти указанного размера нет места.
Действие функции free(), обратное действию функции malloc(). Эта функция освобождает ранее выделенную область памяти.
Выделение памяти и ее обнуление осуществляется функцией calloc() .
Синтаксис:
unsigned n_elem , size_elem ; /* число элементов и размер одного элемента в байтах */
void *calloc (n_ elem, size_elem);
Функция возвращает указатель на выделенный блок памяти, либо
NULL, если память нельзя выделить.
Из приведенных описаний видно, что обе функции возвращают указатель на любой тип (void), следовательно, при обращении к этим функциям необходимо использовать явную операцию преобразования типов.
Освобождение ранее выделенной памяти осуществляется функцией
void free (ptr ):
char *ptr;
ptr = (char*) malloc(…) ;
…
free (ptr);
Пример 7.2: Выделение памяти под массивы
# include<alloc.h>
# include<stdio.h>
# include<conio.h>
# include<stdlib.h>
int main (void)
{
int *mas_1;
float *mas_2;
clrscr ( );
mas_1 = (int*)malloc(10*sizeof (int));
mas_2 = (float*)calloc( 1000,sizeof(float));
uf (mas_1==NULL || mas_2== NULL )
{
printf (“Не хватает памяти ”);
getch ( );
exit (0);
}
printf(“Начало mas_1 %p\n”,mas_1);
printf(“Начало mas_2 %p\n”,mas_2);
getch ( );
free (mas_1);
free (mas_2);
return (1);
}
В С++ для выделения и освобождения памяти используется также функции new() и delete ().
Динамическое распределение памяти удобно использовать тогда, когда заранее неизвестно количество используемых переменных. В частности, этот механизм используется для создания массивов с изменяемым количеством элементов.