Управление памятью в C
Здравствуйте, будущие маги кодирования! Сегодня мы погружаемся в fascинирующий мир управления памятью в C. Не волнуйтесь, если вы новички в программировании; я буду вести вас через это путешествие шаг за шагом, как я делал это для countless студентов на протяжении многих лет моей преподавательской деятельности. Так что надевайте свои виртуальные каски и давайте исследуем строительную площадку компьютерной памяти!
Функции для динамического управления памятью в C
Before мы начнем строить наши memory небоскребы, давайте familiarize ourselves с инструментами, которые мы будем использовать. В C у нас есть набор функций, которые помогают нам управлять памятью динамически. Представьте эти функции как вашу надежную toolboxes:
Функция | Цель |
---|---|
malloc() | Выделяет блок памяти |
calloc() | Выделяет и initializes несколько блоков памяти |
realloc() | Изменяет размер previously выделенного блока памяти |
free() | Возвращает выделенную память системе |
Эти функции как бригада на нашей строительной площадке memory. У каждого есть своя special работа, и мы будем closely знакомиться с ними всеми.
Динамическое выделение памяти
Представьте, что вы planning вечеринку, но не уверены, сколько гостей прийдет. Вот где comes в handy динамическое выделение памяти! Вместо того чтобы устанавливать фиксированное количество стульев, вы можете добавлять или удалять их по мере необходимости. Давайте посмотрим, как мы делаем это в C.
Функция malloc()
Наш первый супергерой memory выделения - malloc()
. Он означает "memory allocation" и используется для запроса блока памяти у системы.
#include <stdio.h>
#include <stdlib.h>
int main() {
int *numbers;
int size = 5;
numbers = (int*)malloc(size * sizeof(int));
if (numbers == NULL) {
printf("Memory allocation failed!\n");
return 1;
}
for (int i = 0; i < size; i++) {
numbers[i] = i * 10;
printf("numbers[%d] = %d\n", i, numbers[i]);
}
free(numbers);
return 0;
}
Давайте разберем это:
- Мы включаем
<stdlib.h>
, потому что это где живетmalloc()
. - Мы declare pointer
numbers
для хранения нашего динамически выделенного массива. -
malloc(size * sizeof(int))
запрашивает достаточно памяти для хранения 5 целых чисел. - Мы cast результат к
(int*)
, потому чтоmalloc()
возвращает void pointer. - Всегда проверяйте, succeeded ли
malloc()
! Если он возвращаетNULL
, у нас нет шансов (и памяти). - Мы можем использовать
numbers
как обычный массив. - Не забудьте
free()
память, когда вы закончите!
Функция calloc()
Теперь встречайте calloc()
, neat freak memory выделения. В то время как malloc()
дает вам память с whatever мусор был там до этого, calloc()
убирает за собой, инициализируя всю выделенную память в ноль.
#include <stdio.h>
#include <stdlib.h>
int main() {
int *numbers;
int size = 5;
numbers = (int*)calloc(size, sizeof(int));
if (numbers == NULL) {
printf("Memory allocation failed!\n");
return 1;
}
for (int i = 0; i < size; i++) {
printf("numbers[%d] = %d\n", i, numbers[i]);
}
free(numbers);
return 0;
}
Основные различия здесь:
-
calloc()
принимает два аргумента: количество элементов и размер каждого элемента. - Все элементы инициализируются в ноль, так что наш вывод будет всеми нулями.
Изменение и высвобождение памяти
Иногда наша вечеринка становится больше или меньше, чем мы ожидали. Вот где comes в handy realloc()
!
Функция realloc()
realloc()
как魔术ник, который может расширять или уменьшать наш блок памяти.
#include <stdio.h>
#include <stdlib.h>
int main() {
int *numbers;
int size = 5;
numbers = (int*)malloc(size * sizeof(int));
if (numbers == NULL) {
printf("Memory allocation failed!\n");
return 1;
}
for (int i = 0; i < size; i++) {
numbers[i] = i * 10;
printf("numbers[%d] = %d\n", i, numbers[i]);
}
// Давайте расширяем наш массив
size = 10;
numbers = (int*)realloc(numbers, size * sizeof(int));
if (numbers == NULL) {
printf("Memory reallocation failed!\n");
return 1;
}
// Заполним новые элементы
for (int i = 5; i < size; i++) {
numbers[i] = i * 10;
}
// Выведем все элементы
for (int i = 0; i < size; i++) {
printf("numbers[%d] = %d\n", i, numbers[i]);
}
free(numbers);
return 0;
}
Вот что происходит:
- Мы начинаем с 5 элементов, как и раньше.
- Мы используем
realloc()
для расширения нашего массива до 10 элементов. -
realloc()
сохраняет нашу исходную данные и дает нам больше места. - Мы заполняем новые элементы и выводим все.
Функция free()
Last но не least, у нас есть free()
, бригада уборки нашей memory управления команде. Всегда помните, чтобы free()
вашу динамически выделенную память, когда вы закончите с ней!
#include <stdio.h>
#include <stdlib.h>
int main() {
int *numbers = (int*)malloc(5 * sizeof(int));
if (numbers == NULL) {
printf("Memory allocation failed!\n");
return 1;
}
for (int i = 0; i < 5; i++) {
numbers[i] = i * 10;
printf("numbers[%d] = %d\n", i, numbers[i]);
}
free(numbers); // Уборка!
numbers = NULL; // Хорошая практика, чтобы избежать использования высвобожденной памяти
// Попытка использовать 'numbers' теперь была бы плохой идеей!
return 0;
}
Помните:
- Всегда
free()
выделяемую вами память, когда вы закончите с ней. - Установите pointer к
NULL
после высвобождения, чтобы избежать случайного использования высвобожденной памяти. - Никогда не пытайтесь
free()
память, которую вы не выделяли динамически.
И вот оно,folks! Мы построили наши memory управление небоскребы, научились выделять место для наших вечеринок, перераспределять место по мере необходимости и убирать afterwards. Помните, хорошее управление памятью как быть хорошим хозяином - всегда убедитесь, что у вас есть достаточно места для ваших гостей, будьте гибки с вашими arrangement и彻底 убирайте после того, как вечеринка закончилась!
Продолжайте практиковать эти концепции, и вскоре вы станете master architect памяти вашей программы. Счастливого кодирования и пусть ваши программы всегда работают без утечек!
Credits: Image by storyset