Подтвердить что ты не робот

Каковы альтернативы malloc() в C?

Я пишу C для платы MPC 555 и вам нужно выяснить, как распределить динамическую память без использования malloc.

4b9b3361

Ответ 1

Обычно malloc() реализуется в Unix с помощью sbrk() или mmap(). (Если вы используете последний, вы хотите использовать флаг MAP_ANON.)

Если вы нацеливаете Windows, может помочь VirtualAlloc. (Более или менее функционально эквивалентно анонимному mmap().)

Обновление: Не понимал, что вы не работаете под полной ОС, у меня как-то сложилось впечатление, что это может быть домашнее задание, выполняющееся поверх системы Unix или что-то в этом роде..

Если вы выполняете встроенную работу, а у вас нет malloc(), я думаю, вам стоит найти диапазон памяти, в котором вам нужно писать, и написать свой собственный malloc(). Или возьмите чужой.

В значительной степени стандартный, который все заимствуют, был написан Дуг Лиа в SUNY Oswego. Например, glibc malloc основывается на этом. См.: malloc.c, malloc.h.

Ответ 2

Если ваша среда выполнения не поддерживает malloc, вы можете найти malloc с открытым исходным кодом и настроить его, чтобы самостоятельно управлять куском памяти.

Ответ 4

malloc() - это абстракция, которая используется для того, чтобы позволить программам C выделять память, не понимая деталей о том, как на самом деле выделяется память из операционной системы. Если вы не можете использовать malloc, у вас нет другого выбора, кроме как использовать любые возможности для распределения памяти, предоставляемые вашей операционной системой.

Если у вас нет операционной системы, вы должны иметь полный контроль над макетом памяти. В то время для простых систем самым простым решением является просто сделать все статичное и/или глобальное, для более сложных систем вы захотите зарезервировать некоторую часть памяти для распределителя кучи, а затем записать (или заимствовать) код, который использует этот памяти для реализации malloc.

Ответ 5

Вы должны объяснить, почему вы не можете использовать malloc(), так как могут быть разные решения по разным причинам, и есть несколько причин, почему это может быть запрещено или недоступно для небольших/встроенных систем:

  • относится к фрагментации памяти. В этом случае решением может быть набор подпрограмм, которые выделяют блоки памяти фиксированного размера для одного или нескольких пулов памяти.
  • среда выполнения не предоставляет malloc(). Я думаю, что большинство современных наборов инструментов для встроенных систем предоставляют некоторый способ связи в реализации malloc(), но, возможно, вы используете тот, который не по какой-либо причине. В этом случае использование Doug Lea public domain malloc может быть хорошим выбором, но может быть слишком большим для вашей системы (я не знакомый с MPC 555 с головы). В этом случае может быть очень простой, настраиваемый malloc() объект. Это не так сложно написать, но убедитесь, что вы unit test черт возьми из uit, потому что также легко получить детали не так. Например, у меня есть набор очень маленьких подпрограмм, которые используют стратегию распределения памяти с мертвой памятью, используя блоки в свободном списке (распределитель может быть настроен на время компиляции для первого, лучшего или последнего соответствия). Я даю ему массив char при инициализации, и последующие вызовы выделения будут разделить свободные блоки по мере необходимости. Это нигде не так сложно, как Lea malloc(), но это довольно мало, поэтому для простых целей это сделает трюк.
  • многие встроенные проекты запрещают использование динамической памяти - в этом случае вам нужно жить со статически выделенными структурами

Ответ 6

Напишите свое. Поскольку ваш распределитель, вероятно, будет специализироваться на нескольких типах объектов, я рекомендую схему Quick Fit, разработанную Биллом Вулфом и Чарльзом Вайнштоком. (Я не смог найти бесплатную копию этой статьи, но многие люди имеют доступ к цифровой библиотеке ACM.) Документ короткий, легко читаемый и хорошо подходит для вашей проблемы.

Если вам понадобится более общий распределитель, лучшим руководством, которое я нашел на тему программирования на машинах с фиксированной памятью, является книга Дональда Кнута Искусство компьютерного программирования, том 1. Если вам нужны примеры, вы можете найти хорошие в донской эпической книжной обработке исходного кода TeX, TeX: Программа.

Наконец, учебник для студентов Bryant и O'Hallaron довольно дорог, но он проходит через реализацию malloc в мучительном деталь.

Ответ 7

Напишите свое. Предварительно выделите большой кусок статической ОЗУ, затем напишите некоторые функции, чтобы захватить и освободить куски. Дух того, что делает malloc(), за исключением того, что он просит ОС распределять и освобождать страницы памяти динамически.

Существует множество способов отслеживания того, что выделяется, а что нет (растровые изображения, используемые/свободные связанные списки, двоичные деревья и т.д.). Вы должны найти множество ссылок с несколькими поисковыми запросами Google.

Ответ 8

Ответ действительно зависит от того, почему вам может потребоваться динамическое выделение памяти. Какая система делает то, что ей нужно распределять память, но не может использовать статический буфер? Ответ на этот вопрос будет определять ваши требования в управлении памятью. Оттуда вы можете определить, какую структуру данных вы хотите использовать для управления вашей памятью.

Например, мой друг написал что-то вроде видеоигры, которые отображали видео в линиях сканирования на экране. Эта команда определила, что память будет выделена для каждой строки сканирования, но существует определенное ограничение на количество байтов, которые могут быть для любой данной сцены. После рендеринга каждой строки сканирования все временные объекты, выделенные во время этого рендеринга, были освобождены.

Чтобы избежать возможности утечки памяти и по соображениям производительности (это было в 90, а компьютеры были медленнее), они использовали следующий подход: они предварительно выделили буфер, который был достаточно большим, чтобы удовлетворить все распределения для scan-line, в соответствии с параметрами сцены, которые определяют максимальный размер. В начале каждой строки сканирования глобальный указатель был установлен в начало строки сканирования. Поскольку каждый объект был выделен из этого буфера, возвращалось значение глобального указателя, и указатель был перенесен в следующую позицию, выровненную по машинному слову, после выделенного количества байтов. (Это дополнение выравнивания включало исходный расчет размера буфера, а в 90 было четыре байта, но теперь должно быть 16 байт на некоторых машинах). В конце каждой строки сканирования глобальный указатель был reset для начало буфера.

В строках "debug" было два буфера сканирования, которые были защищены с использованием защиты виртуальной памяти во время чередующихся строк сканирования. Этот метод обнаруживает, что устаревшие указатели используются от одной линии сканирования до следующей.

Буфер сканирующей памяти можно назвать "пулом" или "ареной" в зависимости от того, о чём вы спрашиваете. Соответствующая деталь заключается в том, что это очень простая структура данных, которая управляет памятью для определенной задачи. Это не общий менеджер памяти (или, соответственно, "реализация свободного хранилища" ), например malloc, который может быть тем, о чем вы просите.

Для отслеживания свободного места на вашем приложении может потребоваться другая структура данных. Каково ваше приложение?

Ответ 9

malloc() и связанные с ним функции - единственная игра в городе. Разумеется, вы можете катить свою собственную систему управления памятью любым способом, который вы выберете.

Ответ 10

Если возникают проблемы с распределением динамической памяти из кучи, вы можете попробовать выделить память из стека с помощью alloca(). Применяются обычные оговорки:

  • Когда вы вернетесь, память исчезнет.
  • Объем памяти, который вы можете выделить, зависит от максимального размера вашего стека.

Ответ 11

Вам может быть интересно: liballoc

Это простая, простая в использовании замена malloc/free/calloc/realloc, которая работает.

Если вы знаете заранее или можете определить доступные области памяти на своем устройстве, вы также можете использовать их libbmmm для управления этими большими блоками памяти и предоставления резервного хранилища для liballoc. Они являются лицензированными и бесплатными BSD.

Ответ 12

FreeRTOS содержит 3 примера реализации распределения памяти (включая malloc()) для достижения различных оптимизаций и использования, подходящих для небольших встроенных систем (AVR, ARM и т.д.). Для получения дополнительной информации см. Руководство FreeRTOS.

Я не вижу порт для MPC555, но вам не составит труда адаптировать код к вашим потребностям.

Ответ 13

Если библиотека, поставляемая вместе с вашим компилятором, не предоставляет malloc, то у нее, вероятно, нет понятия кучи.

Куча (по крайней мере, в системе без OS) - это просто область памяти, зарезервированная для распределения динамической памяти. Вы можете зарезервировать такую ​​область, просто создав статически распределенный массив соответствующего размера, а затем предоставив интерфейс для предоставления непрерывных кусков этого массива по требованию и для управления кусками, которые используются и возвращаются в кучу.

Несколько более простой способ состоит в том, чтобы компоновщик выделял кучу из любой памяти после выделения стека и статической памяти. Таким образом, куча всегда автоматически настолько велика, насколько это возможно, позволяя вам просто использовать всю доступную память. Это потребует модификации компоновщика приложений script. Сценарии компоновщика специфичны для конкретной инструментальной цепочки и являются неизменными несколько загадочными.

K & R включал простую реализацию malloc, например.