Dynamic memory: malloc, free, and realloc · Динамическая память: malloc, free и realloc
Stack memory vs heap memory
- Normal local variables live on the stack. They appear when a function starts and vanish when it returns.
- Sometimes you need memory that outlives the function, or whose size you only know at run time.
- That memory comes from the heap. You ask for it, and later you give it back.
Память стека против памяти кучи
- Обычные локальные переменные живут в стеке. Они появляются при начале функции и исчезают при её возврате.
- Иногда нужна память, которая продержится дольше функции или размер которой известен только во время выполнения.
- Такая память находится в куче. Вы запрашиваете её, а позже возвращаете обратно.
malloc and sizeof
mallocasks the heap for a block of bytes and returns a pointer to it.- Use
sizeofto get the size of one item:malloc(n * sizeof(int))makes room fornints. - The block is yours to use through the pointer, exactly like an array:
a[0],a[1], ...
malloc и sizeof
mallocзапрашивает у кучи блок байтов и возвращает указатель на него.- Используйте
sizeof, чтобы узнать размер одного элемента:malloc(n * sizeof(int))выделяет место подnцелых чисел. - Блок доступен вам через указатель точно как массив:
a[0],a[1], ...
free and memory leaks
- When you are done with heap memory, give it back with
free(pointer). - If you never
freeit, the program leaks memory — it holds space it no longer uses. - Rule for these tasks: your function allocates and returns; the checker frees it. Do not call
freeyourself.
free и утечки памяти
- Когда закончите работу с памятью кучи, верните её с помощью
free(pointer). - Если вы никогда не вызовете
free, программа утечёт памятью — она займет место, которое больше не используется. - Правило для этих заданий: ваша функция выделяет память и возвращает указатель; чекер освобождает её. Не вызывайте
freeсамостоятельно.
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int *a = malloc(3 * sizeof(int)); // room for 3 ints
a[0] = 5; a[1] = 6; a[2] = 7;
printf("%d\n", a[0] + a[1] + a[2]); // 18
free(a); // give it back
return 0;
}
Growing an array with realloc
realloc(a, newSize)resizes a heap block, keeping the old contents.- It may move the block, so always use its return value:
a = realloc(a, ...). - This is how you grow an array one item at a time, like a list that gets longer.
Увеличение массива с помощью realloc
realloc(a, newSize)изменяет размер блока в куче, сохраняя старое содержимое.- Он может переместить блок, поэтому всегда используйте его возвращаемое значение:
a = realloc(a, ...). - Именно так вы растите массив по одному элементу за раз, как список, который становится длиннее.
Common mistakes
- Every
mallocneeds a matchingfree; do not use memory afterfree. - Check that
mallocdid not returnNULL.
Распространенные ошибки
- Каждый
mallocтребует соответствующегоfree; не используйте память послеfree. - Убедитесь, что
mallocне вернулNULL.
Now you try
- Use
malloc(n * sizeof(int))for new arrays, and#include <stdlib.h>. - Your function returns the pointer; the checker frees it — do not call
free. Do not write amain.
Теперь попробуйте сами
- Используйте
malloc(n * sizeof(int))для новых массивов, а#include <stdlib.h>. - Ваша функция возвращает указатель; проверчик освобождает его — не вызывайте не
free. Не пишите неmain.
Complete int *make_array(int n, int value) so it allocates n ints (with malloc), sets every one to value, and returns the pointer. The checker frees it. Do not write a main. · Заполните int *make_array(int n, int value) так, чтобы он выделял ⟨n⟩ int (с помощью malloc), устанавливал каждый на значение value и возвращал указатель. Проверка освободит память. Не пишите ни main.
Click Run to see the output here. · Нажмите Запустить, чтобы увидеть результат здесь.
Complete int *concat(const int a[], int na, const int b[], int nb) so it allocates na + nb ints, copies all of a then all of b, and returns the pointer. The checker frees it. Do not write a main. · Заполните int *concat(const int a[], int na, const int b[], int nb) так, чтобы он выделял ⟨na + nb⟩ int, копировал все элементы из ⟨a⟩, затем все из ⟨b⟩, и возвращал указатель. Проверка освободит память. Не пишите ни main.
Click Run to see the output here. · Нажмите Запустить, чтобы увидеть результат здесь.
Complete int *push(int *a, int *len, int value) so it grows the heap array a to hold one more int with realloc, stores value at the end, increases *len by 1, and returns the new pointer. The checker frees it. Do not write a main. · Заполните int *push(int *a, int *len, int value) так, чтобы он увеличивал динамический массив ⟨a⟩, чтобы он вмещал еще один int с помощью realloc⟩, сохранял ⟨value⟩ в конец, увеличивал ⟨*len⟩ на 1⟩ и возвращал новый указатель. Проверка освободит память. Не пишите ни main.
Click Run to see the output here. · Нажмите Запустить, чтобы увидеть результат здесь.