Привет всем, прежде всего, извиняюсь за то что не тороплюсь выпускать новые статьи, в основном у меня нехватка времени, но в ближайшее время все изменится, а теперь, давайте продолжим наше изучение указателей!
Продолжим мы изучение с разборами основ памяти!
1. Стек и куча
Вся ваша программа загружается целиком в ОЗУ, то есть все ваши переменные, функции находятся в ОЗУ.
И вот как-раз таки память бывает двух типов, это Стэк (англ "Stack") и Куча
Когда вы вызываете какую-то функцию, под вашу функцию в стеке выделятеся память, она контролируется непосредственно процессором и работает довольно быстро, правда имеет она фиксированный размер.
Тут в шестой строке мы создали локальную переменную, которая хранится в стеке и соответсвенно после того как функция завершит свою работу, она будет уничтожена. Иногда это правильно, но иногда мы хотим создать какой-то объект и нам надо возвратить его адрес.
И вы наверняка придумаете что-то вроде этого
То есть, вы создадите некую функцию конструктор которая будет возвращать адрес нового объекта, НО прикол будет в том, что этот объект удалится после завершения функции и ссылка будет недействительной, в лучшем случае компилятор предупредит вас о возвращении адреса локальной переменной, но в худшем, вы попадете - "Не туда, по адресу"
И возникает логичный вопрос: "А что мне делать ?"
Ну, тут все просто, нам надо выделять память не в стеке, а в куче!
И возникат вопрос: "Ну ок, я буду хранить данные в куче, а как их поместить в кучу ?"
2. Функции malloc, free и realloc
В стандартной библиотеке языка Си (stdlib.h), есть замечательный функции free, malloc и realloc!
Они нужны для работы с кучей, начнем с malloc!
Malloc - функция которая принимает в качестве агрументы количество байтов, которые нужно выделить и соответсвенно возвращает указатель на выделенную память.
Тут все предельно просто, но зачем я использовал sizeof ?
Конечно же, я знаю что под int мне надо выделить 4 байта (ну или восемь в моем случае) но я хочу, чтобы мой код был более-менее переносимым и соответсвенно я не хочу каждый раз читать сколько байтов нужно выделить под что-то, пусть компилятор вычислит это сам!
PS: Функция sizeof это единственная функция в языке Си которая принимает тип, то что она получает на вход преобразовывается в число, во время компиляции.
Free() the Malloc() xD
Теперь, нам мы можем передавать этот "x" куда угодно, даже если функция которая вернула на него указатель завершит свою работу, память не будет освобождена, но опять же нам надо все-таки избавляться от объекта, ибо он нам когда-то больше не будет нужен. Для этого можно воспользоватся функцией free которая принимает указатель и возвращает всю память операционной системе, все предельно просто.
А зачем мне Realloc ?
Иногда нужно изменить размер выделенной памяти, в принципе можно сделать так:
- 1. Выделить память(больше или меньше предыдущего)
- 2. Скопировать туда данные из старого участка в новый
- 3. Освободить старый участок
Но можно это сделать с помощью функции realloc
Достаточно сделать так:
realloc(pointer_var, size) // Где size это новый размер
Всё это будет хорошо работать, теперь давайте перепишем нашу предыдущую программу, дабы закрепить пройденное.
Как видите, все работает, заметьте что память по возможности надо очищать (под возможностью я имею ввиду ненадобность в этой памяти)
Если вы не будете это делать, да еще и перезапишите переменную-указатель то - получите так называемую утечку памяти. Конечно они не критичны если ваша программа маленькая, но факт остается фактом, очищать память нужно!
На последок, хочу рассказать об операторе "->"
Оператор "->" - Сначала разыменовывает, а потом обращается к члену, например без него мы можем сделать это так
printf("%d", *c.x) // xD
printf("%d", c->y) // Просто так - выглядит круче!
На этом у меня - Всё!
Я очень старался чтобы объяснить все качественно и просто, и если быть до конца честным, я пишу эту статью уже раз в третий, поэтому не пожалейте свой лайк и подписки, спасибо за чтение, обязательно пишите в комменты свои вопросы и предложения в комментах.
А также подписывайтесь на наш Telegram
Удачи в становлении программистом!