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

Этот вопрос задали мне в интервью.

Предположим, что символ *p=malloc (n) присваивает больше, чем n, скажите, что байты N памяти выделяются и свободны (p), используется для освобождения памяти, выделенной p.

диспетчер "кучи" может выполнить такое дефектное выделение? что происходит теперь, будут n байты освобождаться, или байты N освобождены?

там какой-либо метод должен найти, сколько памяти освобождено?

Править

там какой-либо метод должен найти, сколько памяти освобождено?

лучше, чем ничего,

mallinfo () может пролить некоторый свет, как указано "Fred Larson"

8
задан Rozuur 25 February 2010 в 19:12
поделиться

5 ответов

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

Простая реализация могла бы, например, сохранить только размер блока в пространстве, непосредственно предшествующем возвращаемому указателю. Тогда free () будет выглядеть примерно так:

void free(void *ptr)
{
    size_t *size = (size_t *)ptr - 1;

    return_to_heap(ptr, *size);
}

Где return_to_heap () используется здесь для обозначения функции, которая выполняет фактическую работу по возврату указанного блока памяти в куча впрок.

8
ответ дан 5 December 2019 в 11:24
поделиться

Да, менеджеру кучи разрешено возвращать блок размером более n байт. Совершенно безопасно (и необходимо!) освободить возвращенный указатель с помощью free, а free деаллоцирует весь блок.

Многие реализации кучи отслеживают свои выделения, вставляя в кучу блоки метаданных. free будет искать эти метаданные, чтобы определить, сколько памяти нужно деаллоцировать. Однако это зависит от конкретной реализации, поэтому нет способа узнать, сколько malloc отдал вам памяти, и, в общем, вас это не должно волновать.

4
ответ дан 5 December 2019 в 11:24
поделиться

Да, это происходит почти каждый раз, когда вы malloc () . Заголовок блока malloc содержит информацию о размере блока, и когда вызывается free () , он возвращает эту сумму обратно в кучу. Это не неисправно, это ожидаемая операция.

Простая реализация может, например, хранить только размер блока в пространстве, непосредственно предшествующем возвращаемому указателю. Тогда free () будет выглядеть примерно так:

void free(void *ptr)
{
    size_t *size = (size_t *)ptr - 1;

    return_to_heap(ptr, *size);
}

Где return _ to _ heap () используется здесь для обозначения функции, которая выполняет фактическую работу возврата указанного блока памяти в кучу для будущего использования.

-121--3612603-

Обычно диспетчер кучи освобождает все выделенное. Она хранит эту информацию где-то и ищет ее, когда вызывается free () .

Диспетчер кучи не «неисправен», если он выделяет больше памяти, чем было запрошено. Менеджеры кучи часто работают с фиксированными размерами блоков и округляются до следующего соответствующего размера блоков при удовлетворении запроса. Задача кучного менеджера должна быть максимально эффективной, и часто большая эффективность является результатом небольшой неэффективности.

-121--3612605-

Это поведение malloc по умолчанию. Он возвращает значение NULL или указатель на раздел памяти, по крайней мере, столько, сколько требуется. Так что да свободный должен уметь справляться с избавлением от памяти дольше, чем было предложено.

Выяснение того, какой объем памяти был на самом деле свободен или выделен, является вопросом конкретной платформы.

1
ответ дан 5 December 2019 в 11:24
поделиться

Другие ответы хорошо объяснили, как обрабатывается размер блока. Чтобы узнать, сколько памяти было освобождено, единственное решение, которое я могу придумать, это вызвать mallinfo() до и после освобождения.

1
ответ дан 5 December 2019 в 11:24
поделиться

Обычно диспетчер кучи освобождает все, что он выделил. Он где-то хранит эту информацию и ищет ее при вызове free () .

Диспетчер кучи не является «неисправным», если он выделяет больше памяти, чем было запрошено. Менеджеры кучи часто работают с фиксированными размерами блоков и округляют до следующего подходящего размера блока при удовлетворении запроса. Работа диспетчера кучи заключается в том, чтобы быть максимально эффективным, и часто большая эффективность является результатом нескольких небольших неэффективностей.

1
ответ дан 5 December 2019 в 11:24
поделиться