Модель памяти в языке Си

17.12.2020

Модель памяти в языке Си — система хранения объектов в языке Си.

Способ хранения объекта в языке Си определяет его время жизни — часть времени выполнения программы, во время которого объект существует или для него зарезервировано место. Объект имеет постоянный адрес и сохраняет своё последнее значение. Запрещается обращаться к объекту, который перестал существовать, при этом, если при работе с объектом использовался указатель, его значение остаётся неопределённым.

Существует три способа хранения объектов: автоматический, статический и динамический.

Статический объект можно инициализировать явно, либо использовать умалчиваемую инициализацию.

При использовании функции calloc все объекты имеют нулевое значение кроме чисел с плавающей запятой и указателей.

Выражения, не являющиеся lvalue, связанные с обращением к массиву, являющегося членом структуры (struct) или объединения (union) имеют время существования, ограниченное оценкой такого выражения.

Си-строки, которыми инициализируются указатели char*, имеют статический тип хранения и не должны изменяться.

Динамическая память

Ни один объект не может находиться в динамической памяти без явного указания программиста. Для работы с динамической памятью существуют функции malloc, calloc, realloc и free. Поскольку функции, выделяющие память, принимают размер в переменной типа size_t, максимальный объём выделяемой памяти ограничен SIZE_T_MAX.

Функции malloc и calloc выделяют память, которая после использования должна быть освобождена с помощью вызова free. После освобождения значение указателя остаётся неопределённым. Функция realloc возвращает указатель на изменённый блок памяти, если запрос не может быть удовлетворён, размер блока памяти не изменяется.

1#include <stdlib.h> 2 3void foo (void **ptr, size_t size) 4{ 5 *ptr = realloc (*ptr, size+128); /* утечка памяти, если realloc вернёт NULL */ 6 if (!*ptr) 7 { 8 ... 9 } 10}

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

Пример

#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; }

Имя:*
E-Mail:
Комментарий:
Информационный некоммерческий ресурс fccland.ru © 2020
При цитировании и использовании любых материалов ссылка на сайт обязательна