Доброй ночи, меня интересует как СИ (в данном случаи компилятор? ) выделяет память. Сейчас не будем вдаваться в объяснения выделения памяти в ОС. А поясните, как компилятор задаёт команду программе освободить какойто участок. Вот например. (ничего если я буду использовать функции ядра линекса? от этого суть не меняется..) есть структура struct test { её тело } struct test *test_ptr; выделяем память test_ptr = kmalloc(sizeof(struct test) , GFP_ATOMIC ); Как понимаю компилятор создаёт обращение к ОС запросом на выделение какогото физ. участка памяти, размером sizeof(struct test).. верно? затем чтоб освободить этот участок, мы пишеи kfree(test_ptr) тоесть при создании кода компилятор запоминает что указатель test_ptr указывает на структуру размером sizeof(struct test) и генерит код - запрос к ОС о очистке выделенной памяти начиная с адреса test_ptr и размером sizeof(struct test) Верно? тоесть в рамках одной функции Код (Text): struct test { её тело } struct test *test_ptr; выделяем память test_ptr = kmalloc(sizeof(struct test) , GFP_ATOMIC ); kfree(test_ptr); Отработает на отлично Но, что если разделить запросы на выделение и очистку память в двух разных функциях. Код (Text): struct test { unsigned char *address_ptr; // тут сохраняем адрес выделенной памяти element_1; element_2; .... element_n; } struct test *test_ptr; int main() { func_malloc(); func_free(); } func_malloc() { test_ptr = kmalloc(sizeof(struct test) , GFP_ATOMIC ); test_ptr->address_ptr = test_ptr; // сохранили адрес, указывающий на начало выделенной памяти под структуру } func_free() { // тут надо очистить память по адресу занесённому в test_ptr->address_ptr kfree( test_ptr->address_ptr ); } Вопрос таков, как в таком случаи компилятор понемает, сколько нужно очистить байт. Или если он этого не понимает, то как сделать, чтоб kfree очистило память по test_ptr->address_ptr размером sizeof(struct test)
Поддержка динамической памяти происходит в рантайме, а не на этапе компиляции. Программа обращается к куче. Куча по необходимости запрашивает у системы память и ведёт учет занятых/свободных блоков.
Booster А как правильно освободить участок выделенной памяти, начало которой записано в test_ptr->address_ptr и размером sizeof(struct test) (выделение памяти в одной функции а её освобождение происходит в другой функции)
В твоём случае kfree(test_ptr->address_ptr); Размер куча тоже хранит, поэтому достаточно передать указатель. В ядре ядрённая куча, но смысла это не меняет.
Мне в коде нужно именно через сохранённый адрес в test_ptr->address_ptr память очищать. Сделал очистку так kfree((struct test *)test_ptr->address_ptr); Вроде после запуска проги, ничего не падает и очистка работает нормально.
Booster Структуры создаются в N-количестве, и заносятся в двусвязанный список. (первая функция) А вторая в выгрузке моего модуля, обходит весь двусвязанный список, проверяет каждую структуру, делает какието действия по копированию и тд.. затем удаляет структуру из двусвязанного списка и делает kfree больше не нужной структуры. Я намудрил? и можно просто в kfree передавать указатель на удаляемую структуру? (перед kfree предварительно удалив структуру из двусвязанного списка)
Куча фиктивно расширяется. Для этого необходимо запрос дать. Стек реально расширяется. Там сторожевые страницы используются. Резервируем сколько нужно памяти. Выделяем страницу в начале этого региона, страницу выше или ниже делаем не доступной(PTE.P и тд). Когда обращение происходит в пределах сторожевой страницы она выделяется, а следующая страница делается сторожевой(менеджер памяти является хэндлером #PF). Ядро вини кроме стека пользователю подобный функционал не даёт, поэтому менеджер памяти необходимо самому ваять. хз как там в линус. А компиль совсем к этому отношения не имеет.