malloc и free
Выделяйте память в куче
«malloc и free» — бесплатный урок C Academy на CoddyKit. Это урок 1 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения C Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс C Academy содержит 4 уроков всего.
Куча
До сих пор переменные хранились в стеке с фиксированным временем жизни. Куча позволяет запрашивать память во время выполнения и хранить её столько, сколько необходимо.
Вы самостоятельно управляете памятью кучи с помощью функций из <stdlib.h>.
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int *p = malloc(sizeof(int));
*p = 99;
printf("%d\n", *p);
free(p);
return 0;
}Вызов malloc
malloc(size) резервирует size байт и возвращает указатель на них или NULL в случае ошибки.
Память остаётся неинициализированной: её содержимое не определено.
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int *p = malloc(sizeof(int));
*p = 7;
printf("value = %d\n", *p);
free(p);
return 0;
}Определение размера с помощью sizeof
Всегда задавайте размер выделяемой памяти с помощью sizeof, чтобы код работал правильно на любой платформе.
Запись sizeof(*p) автоматически связывает размер с типом указателя.
#include <stdio.h>
#include <stdlib.h>
int main(void) {
double *p = malloc(sizeof(*p));
*p = 3.14;
printf("%f\n", *p);
free(p);
return 0;
}Всегда проверяйте NULL
Если выделение памяти завершается ошибкой, malloc возвращает NULL. Разыменование этого указателя приводит к аварийному завершению программы.
Проверяйте результат перед использованием.
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int *p = malloc(sizeof(int));
if (p == NULL) {
printf("allocation failed\n");
return 1;
}
*p = 5;
printf("ok: %d\n", *p);
free(p);
return 0;
}Выделение памяти под массив
Чтобы разместить множество элементов, умножьте размер элемента на их количество.
malloc(n * sizeof(int)) создаёт место для n целых чисел.
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int n = 5;
int *arr = malloc(n * sizeof(int));
for (int i = 0; i < n; i++) arr[i] = i * i;
for (int i = 0; i < n; i++) printf("%d ", arr[i]);
printf("\n");
free(arr);
return 0;
}Доступ к массивам в куче через индексы указателя
Доступ к массиву в куче выполняется через его указатель с помощью знакомого синтаксиса arr[i], который эквивалентен *(arr + i).
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int *arr = malloc(3 * sizeof(int));
arr[0] = 10;
*(arr + 1) = 20;
arr[2] = 30;
printf("%d %d %d\n", arr[0], arr[1], arr[2]);
free(arr);
return 0;
}Освобождение памяти
free(p) возвращает блок распределителю памяти. После этого нельзя использовать p для доступа к этой памяти.
Каждому успешному вызову malloc должен соответствовать вызов free.
#include <stdio.h>
#include <stdlib.h>
int main(void) {
char *buf = malloc(16);
if (buf) {
buf[0] = 'A';
printf("%c\n", buf[0]);
free(buf);
}
return 0;
}free(NULL) безопасен
Вызов free для указателя NULL ничего не делает и полностью допустим.
Это упрощает очистку, которая может выполняться до успешного выделения памяти.
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int *p = NULL;
free(p);
printf("free(NULL) was safe\n");
return 0;
}Возврат памяти из кучи
В отличие от переменных стека, память в куче сохраняется после возврата из функции. Благодаря этому функция может выделить память и вернуть буфер.
#include <stdio.h>
#include <stdlib.h>
int *make_range(int n) {
int *a = malloc(n * sizeof(int));
for (int i = 0; i < n; i++) a[i] = i;
return a;
}
int main(void) {
int *r = make_range(4);
printf("%d %d\n", r[0], r[3]);
free(r);
return 0;
}Не приводите тип результата malloc в C
В C malloc возвращает значение типа void *, которое автоматически преобразуется в любой тип указателя.
Явное приведение не нужно и может скрыть отсутствие подключения <stdlib.h>.
#include <stdio.h>
#include <stdlib.h>
int main(void) {
long *p = malloc(sizeof(long));
*p = 1234567L;
printf("%ld\n", *p);
free(p);
return 0;
}Не освобождайте память дважды
Вызов free для одного и того же указателя дважды приводит к неопределённому поведению и может повредить кучу.
После освобождения присваивайте указателю значение NULL, чтобы случайное повторное использование не причинило вреда.
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int *p = malloc(sizeof(int));
*p = 1;
free(p);
p = NULL;
free(p);
printf("no double free\n");
return 0;
}Быстрая проверка
Проверьте свои знания о malloc и free.
Повторение
Вы изучили основы выделения памяти в куче:
malloc(size)резервирует неинициализированные байты и возвращаетNULLв случае ошибки.- Всегда проверяйте результат и размер с помощью
sizeof. free(p)возвращает память; каждому вызову malloc нужен один вызов free.free(NULL)безопасен; повторное освобождение приводит к неопределённому поведению.
Часто задаваемые вопросы
Урок «malloc и free» бесплатный?
Да — полный текст урока «malloc и free» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс C Academy, подпишись на CoddyKit PRO. Курс C Academy содержит 4 уроков всего.
Чему я научусь в уроке «malloc и free»?
Выделяйте память в куче Ты практикуешь C Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать C Academy?
Предыдущий опыт не требуется. C Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 1 из 4.
Сколько времени занимает урок «malloc и free»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке C Academy?
Да. Каждый урок C Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- malloc и free
- calloc и realloc
- Утечки памяти
- Висячие указатели