Лучшие вопросы
Таймлайн
Чат
Перспективы

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

Из Википедии, свободной энциклопедии

Remove ads

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

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

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

Подробнее Свойство, Автоматический ...

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

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

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

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

Remove ads

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

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

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

#include <stdlib.h>

void foo (void **ptr, size_t size)
{
   *ptr = realloc (*ptr, size+128); /* утечка памяти, если realloc вернёт NULL */
   if (!*ptr)
   {
     ...
   }
}

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

Remove ads

Пример

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

Примечания

Loading related searches...

Wikiwand - on

Seamless Wikipedia browsing. On steroids.

Remove ads