Этот вопрос задали мне в интервью.
Предположим, что символ *p=malloc (n) присваивает больше, чем n, скажите, что байты N памяти выделяются и свободны (p), используется для освобождения памяти, выделенной p.
диспетчер "кучи" может выполнить такое дефектное выделение? что происходит теперь, будут n байты освобождаться, или байты N освобождены?
там какой-либо метод должен найти, сколько памяти освобождено?
Править
там какой-либо метод должен найти, сколько памяти освобождено?
лучше, чем ничего,
mallinfo () может пролить некоторый свет, как указано "Fred Larson"
Да, это то, что происходит почти каждый раз, когда вы вызываете malloc ()
. Заголовок блока malloc
содержит информацию о размере блока, и когда вызывается free ()
, он возвращает это количество обратно в кучу. Это не неисправность, это ожидаемая работа.
Простая реализация могла бы, например, сохранить только размер блока в пространстве, непосредственно предшествующем возвращаемому указателю. Тогда free ()
будет выглядеть примерно так:
void free(void *ptr)
{
size_t *size = (size_t *)ptr - 1;
return_to_heap(ptr, *size);
}
Где return_to_heap ()
используется здесь для обозначения функции, которая выполняет фактическую работу по возврату указанного блока памяти в куча впрок.
Да, менеджеру кучи разрешено возвращать блок размером более n байт. Совершенно безопасно (и необходимо!) освободить возвращенный указатель с помощью free
, а free
деаллоцирует весь блок.
Многие реализации кучи отслеживают свои выделения, вставляя в кучу блоки метаданных. free
будет искать эти метаданные, чтобы определить, сколько памяти нужно деаллоцировать. Однако это зависит от конкретной реализации, поэтому нет способа узнать, сколько malloc
отдал вам памяти, и, в общем, вас это не должно волновать.
Да, это происходит почти каждый раз, когда вы malloc ()
. Заголовок блока malloc
содержит информацию о размере блока, и когда вызывается free ()
, он возвращает эту сумму обратно в кучу. Это не неисправно, это ожидаемая операция.
Простая реализация может, например, хранить только размер блока в пространстве, непосредственно предшествующем возвращаемому указателю. Тогда free ()
будет выглядеть примерно так:
void free(void *ptr)
{
size_t *size = (size_t *)ptr - 1;
return_to_heap(ptr, *size);
}
Где return _ to _ heap ()
используется здесь для обозначения функции, которая выполняет фактическую работу возврата указанного блока памяти в кучу для будущего использования.
Обычно диспетчер кучи освобождает все выделенное. Она хранит эту информацию где-то и ищет ее, когда вызывается free ()
.
Диспетчер кучи не «неисправен», если он выделяет больше памяти, чем было запрошено. Менеджеры кучи часто работают с фиксированными размерами блоков и округляются до следующего соответствующего размера блоков при удовлетворении запроса. Задача кучного менеджера должна быть максимально эффективной, и часто большая эффективность является результатом небольшой неэффективности.
-121--3612605- Это поведение malloc по умолчанию. Он возвращает значение NULL
или указатель на раздел памяти, по крайней мере, столько, сколько требуется. Так что да свободный должен уметь справляться с избавлением от памяти дольше, чем было предложено.
Выяснение того, какой объем памяти был на самом деле свободен или выделен, является вопросом конкретной платформы.
Другие ответы хорошо объяснили, как обрабатывается размер блока. Чтобы узнать, сколько памяти было освобождено, единственное решение, которое я могу придумать, это вызвать mallinfo()
до и после освобождения.
Обычно диспетчер кучи освобождает все, что он выделил. Он где-то хранит эту информацию и ищет ее при вызове free ()
.
Диспетчер кучи не является «неисправным», если он выделяет больше памяти, чем было запрошено. Менеджеры кучи часто работают с фиксированными размерами блоков и округляют до следующего подходящего размера блока при удовлетворении запроса. Работа диспетчера кучи заключается в том, чтобы быть максимально эффективным, и часто большая эффективность является результатом нескольких небольших неэффективностей.