Перейти к содержанию

Всё о работе с ОЗУ в C

fresco

В данной статье мы разберём, как программа на языке C взаимодействует с оперативной памятью (ОЗУ), и какие ключевые области памяти она использует. Примеры и объяснения помогут понять, как распределяется память для переменных, функций и данных, а также как C предоставляет доступ к этой памяти через указатели.


Основные области памяти процесса

Когда вы запускаете программу на C, операционная система (ОС) выделяет для неё определённый участок оперативной памяти. Оперативная память процесса делится на несколько областей:

  1. Куча (Heap) — используется для динамического выделения памяти (обычно размером около 1 МБ).
  2. Стек (Stack) — используется для временного хранения данных, таких как параметры функции и локальные переменные (обычно размером около 1 МБ).
  3. Код программы (Code) — содержит сам машинный код программы.
  4. Данные программы (Data) — здесь хранятся глобальные и статические переменные.
Mind Map

В нашей схеме указано, что программа получает доступ к своему выделенному блоку памяти в ОЗУ, и эти области разделены для обеспечения безопасности и оптимизации выполнения программы. Размеры памяти в 1 МБ для кучи и стека являются типичными значениями, которые могут варьироваться в зависимости от системы.


Пример использования памяти: программа "Hello, World!"

Рассмотрим простую программу на C, которая выводит текст "Hello, World!" в стандартный вывод (экран).

#include <stdio.h>

int main() {
    printf("Hello, World!\n");
    return 0;
}

При запуске этой программы в ОЗУ происходит следующее:

  • Область кода: Здесь хранится машинный код, созданный на основе кода программы.
  • Область данных: Если бы в программе были глобальные переменные, они бы хранились здесь.
  • Стек: Создаётся рамка стека для функции main, где хранятся локальные переменные и параметры.
  • Куча: В данной программе не используется, так как нет динамического выделения памяти (но могла бы быть использована с помощью функций malloc, calloc или realloc).

Куча (Heap) и стек (Stack)

  • Куча: Область памяти для данных, размер которых определяется во время выполнения программы. Например, если нам заранее неизвестен размер массива, мы можем выделить память динамически через malloc или calloc. Память в куче нужно освобождать вручную с помощью free, иначе это приведёт к утечкам памяти.

    int *arr = (int *)malloc(5 * sizeof(int)); // Выделение памяти для массива из 5 элементов
    if (arr != NULL) {
        // работа с массивом
        free(arr); // Освобождение памяти
    }
    
    * Стек: Область памяти для временного хранения данных функции. Каждый вызов функции добавляет рамку в стек, где хранятся параметры функции и её локальные переменные. При завершении функции эта память автоматически освобождается.

    void function() {
        int localVar = 10; // Локальная переменная, хранящаяся в стеке
    }
    

    Если стек переполняется из-за слишком большого количества вызовов функций (например, при бесконечной рекурсии), программа завершится с ошибкой.

Стандартные потоки

В схеме также упомянуты стандартные потоки:

  • stdin (0) — стандартный поток ввода (обычно клавиатура).
  • stdout (1) — стандартный поток вывода (обычно экран).
  • stderr (2) — стандартный поток для вывода ошибок.

Эти потоки позволяют взаимодействовать с пользователем и выводить данные. Например:

printf("Output message\n");    // Выводит сообщение в stdout
fprintf(stderr, "Error!\n");   // Выводит сообщение об ошибке в stderr

Работа с указателями и адресами в памяти

В языке C указатели — это переменные, которые содержат адреса других переменных. Например:

int a = 10;
int *p = &a; // Указатель на переменную a

Указатель p будет содержать адрес переменной a, а не её значение. Это позволяет манипулировать памятью, передавать адреса в функции и работать с массивами.


Итоговая схема расположения памяти

Область Описание Пример
Код Машинный код программы Функции и операторы
Данные Глобальные и статические переменные int global_var;
Куча (Heap) Динамически выделенная память malloc, calloc
Стек (Stack) Память для временных данных функций Локальные переменные
Стандартные потоки Взаимодействие с пользователем stdin, stdout, stderr

Эта схема помогает понять, как управляется память в программе на C и как эффективно использовать её ресурсы.


I am a patient boy
I wait, I wait, I wait, I wait
My time's like water down a drain