Interested Article - Модель памяти в языке Си
- 2020-01-23
- 1
Модель памяти в языке Си — система хранения объектов в языке Си .
Способ хранения объекта в языке Си определяет его время жизни — часть времени выполнения программы, во время которого объект существует или для него зарезервировано место. Объект имеет постоянный адрес и сохраняет своё последнее значение. Запрещается обращаться к объекту, который перестал существовать, при этом, если при работе с объектом использовался указатель, его значение остаётся неопределённым.
Существует три способа хранения объектов : автоматический, статический и динамический .
Свойство | Автоматический | Статический | Динамический |
---|---|---|---|
Объявление |
Объект без связывания и без
static
|
Имеет внутреннее или внешнее
связывание
или объявлен с квалификатором
static
|
Выделен с помощью
malloc
|
Время существования | Блок, в котором объявлен объект | Всё время выполнения программы |
От вызова
malloc
до вызова
free
|
Инициализация | Отсутствует в случае отсутствия явной инициализации | Происходит один раз до запуска программы |
Частично в случае
calloc
|
Размер | Фиксированный, неизменяемый | Фиксированный, неизменяемый | Любой, изменяемый |
Типичное размещение | Стек или регистры процессора | Отдельный сегмент памяти | Куча |
Статический объект можно инициализировать явно, либо использовать умалчиваемую инициализацию.
При использовании функции
calloc
все объекты имеют нулевое значение кроме чисел с плавающей запятой и указателей
.
Выражения, не являющиеся
lvalue
, связанные с обращением к массиву, являющегося членом
структуры
(
struct
) или объединения (
union
) имеют время существования, ограниченное оценкой такого выражения
.
Си-строки, которыми инициализируются указатели
char*
, имеют статический тип хранения и не должны изменяться
.
Динамическая память
Ни один объект не может находиться в динамической памяти без явного указания программиста. Для работы с динамической памятью существуют функции
malloc
,
calloc
,
realloc
и
free
. Поскольку функции, выделяющие память, принимают размер в переменной типа
size_t
, максимальный объём выделяемой памяти ограничен
SIZE_T_MAX
.
Функции
malloc
и
calloc
выделяют память, которая после использования должна быть освобождена с помощью вызова
free
. После освобождения значение указателя остаётся
неопределённым
. Функция
realloc
возвращает указатель на изменённый блок памяти, если запрос не может быть удовлетворён, размер блока памяти не изменяется
.
#include <stdlib.h>
void foo (void **ptr, size_t size)
{
*ptr = realloc (*ptr, size+128); /* утечка памяти, если realloc вернёт NULL */
if (!*ptr)
{
...
}
}
При работе с динамической памятью возможны утечки памяти и ошибки двойного освобождения блока.
Пример
#include <stdlib.h>
#include <string.h>
static int x; /* 0 по умолчанию, существует всё время выполнения */
static int y=45; /* 45, существует всё время выполнения */
int cnt(void)
{
static int i=0;/*статический тип, инициализируется нулём только при запуске
программы, а не каждый вызов функции */
int j=-1;/*автоматический тип, инициализируется каждый раз
при вызове функции -1*/
i++;/* увеличивается на 1 в статической области памяти каждый запуск функции*/
j++;/* увеличивается на 1 локальная переменная */
return (i+j);/*при первом вызове с запуска программы функция вернёт 1,
при втором вызове 2, ... */
}
int main (void)
{
char arr[50] = "This is object of automatic storage duration";
/* имеет автоматический тип,существует до выхода из main,
начальные 45 элементов массива инициализированы элементами
строки с закрывающим нулём, остальные не определены */
char *line = "Simple line"; /*автоматический тип, существует до выхода
из main, line инициализирован указателем на константу */
int y; /* значение не определено, существует до выхода из main*/
int z=10; /* значение определено, существует до выхода из main*/
char *ptr; /* значение указателя не определено */
ptr = malloc (50); /* значение по указателю не определено,
объект по указателю существует до вызова free */
strcpy (ptr, arr);
free (ptr);
return 0;
}
Примечания
- ↑ . Дата обращения: 5 августа 2011. 15 августа 2011 года.
- . Дата обращения: 5 августа 2011. 15 августа 2011 года.
- . Дата обращения: 8 августа 2011. 11 августа 2011 года.
- 2020-01-23
- 1