вообще использовать ручное выделение памяти с помощью malloc() в си? Какой в этом смысл? Когда без этого нельзя обойтись? Вот к примеру (надеюсь я правильно понимаю) если мы обьявим массив, без указания размера int ar[ ]; А потом будем его где-то инициализировать, то компилятор сам выделит нужное количество динамической памяти и сам освободит его потом.
Нет, в классическом Си компилятор не выделит сам память в рантайме.
Так нельзя объявлять, размер должен быть указан, либо взят по количеству элементов в инициализации
Компилятор не освободит)
Ну или ОС
Вообще, если вы только изучаете Си, то можете спокойно забыть про динамическое выделение памяти, тем более что MISRA его не рекомендует.
ОС освободит память только после завершения программы. Есть даже такая проблема - "утечка памяти". Это когда программа запрашивает все новые блоки, а старые не возвращает.
а malloc/free не в runtime работают?
Так не сами же по себе.
А можно и не забыть
советую почитать про память, что такое стек, что такое куча. В Си, как и в голом С++, автоматически нечего с памятью не происходит, всё ручками, ручками
Я мб неправ, но c++ также не даст использовать new, если malloc не определён.
Ну механизм выделения памяти должен быть реализован, это да.
Сергей,качаешь вот эту книгу: https://m.vk.com/wall-54530371_4760 и начинаешь изучать Си, вопросы такого рода отпадут сами по себе))
😂😂 надо ещё лучше учить!
Да, попробовал точно нельзя так сделать. Что-то в голове смешалось. Но все же не понятно, чем будет отличаться к примеру int ar[18] и то же самое, сделанное с помощью malloc, ведь и там и там надо знать, какой размер памяти нужен.
Временем жизни, областью видимости как минимум
Тоже про это прочитал, важное замечание
В плюсах можно и перегрузить операторы new/delete под свой тип, для логов например))
int arr[18] - может располагаться как минимум в 3-х местах в памяти в зависимости от контекста. а malloc всегда в куче ( если вы его не переопределяли)
int ar[18]; память выделена на стеке функции, объем 18 * sizeof(int) байт . освобожжать не надо , при выходе из функции стековый фрейм будет разрушен. int* ptr_to_ar = (int *)malloc(18 * sizeof(int)); память выделена в куче процесса, объем, в данном случае - тоже 18 * sizeof(int) байт. надо вернуть в кучу этот блок памяти, когда больше не нужен. но вообще, да - надо тщательнее учить матчасть. что такое массивы, указатели, что у них общего. типы данных и указателей, области видимости переменных.
А если у тебя в программе будет массив из структур например миллионного размера, как ты думаешь как это повлияет на память? struct Person[1000000];
Да я про то, что в смысле динамической памяти си от c++ не особо отличается. Нужен механизм выделения. Но про перегруз для логов я как-то не задумывался даже. Прикольно. Надо попробовать, спасибо)
))) Попробуй, вещь👍 Ну да, почти не отличается, кроме того что new в случае чего кидает исключение
Спасибо за такой детальный ответ!
А прямо в физической памяти можно жёстко выделить, по нужному адресу?
нет. пользовательским процессам доступна только виртуальная память. в большинстве систем.
Я скорее про барметал.
думаю, что можно. но как - не знаю. сходу не скажу.
Размечаешь свободную память под кучу) Выделяешь память размером с кучу.
он хочет массив на стеке. но знать точно адрес , по которому он положит этот массив.
Скорее в куче и чтоб компилятор туда больше ничего не клал
можно тогда . адрес начала кучи известен. как работает аллокатор, тоже известно.
Сделать в скрипте линкера секцию по интересующему адресу и положить переменную туда с помощью attribute ((section)).
Есть new (std::nothrow) который не кидает, вернет nullptr, если аллоцировать не удалось.
Обсуждают сегодня