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

6
задан Community 23 May 2017 в 12:15
поделиться

4 ответа

Большинство реализаций функций распределения памяти C хранят учетную информацию для каждого блока, встроенного или отдельно.

Один из типичных способов (встроенный) состоит в том, чтобы фактически выделить и заголовок, и запрошенную память, заполненную до некоторого минимального размера. Так, например, если вы запросили 20 байтов, система может выделить 48-байтовый блок:

  • 16-байтовый заголовок, содержащий размер, специальный маркер, контрольную сумму, указатели на следующий / предыдущий блок и так далее.
  • 32 байта области данных (ваши 20 байтов дополнены до числа, кратного 16).

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

Имейте в виду, что размер заголовка и заполнения полностью определяется реализацией (на самом деле, все это определяется реализацией a , но опция inline-Accounting-info является общей).

Контрольные суммы и специальные маркеры, которые существуют в учетной информации, часто являются причиной ошибок типа «Память повреждена», если вы их перезаписываете. Заполнение (чтобы сделать распределение более эффективным) - вот почему вы иногда можете написать немного за пределами запрошенного пространства, не вызывая проблем (тем не менее, не делайте этого, это поведение undefined и, только потому, что оно иногда работает, не работает » означает, что это нормально).


a Я написал реализации malloc во встроенных системах, где у вас было 128 байтов независимо от того, что вы запрашивали (это был размер самой большой структуры в системе) и простой Не встроенная битовая маска использовалась, чтобы решить, был ли выделен 128-байтовый блок или нет.

У других, которые я разработал, были разные пулы для 16-байтовых фрагментов, 64-байтовых фрагментов, 256-байтовых фрагментов и 1 КБ фрагментов, опять же с использованием битовой маски, чтобы уменьшить накладные расходы на учетную информацию и увеличить скорость malloc и free (нет необходимости объединять смежные свободные блоки), что особенно важно в среде, в которой мы работали.

8
ответ дан 8 December 2019 в 18:32
поделиться

Когда вы выделяете блок памяти, выделяется больше байт, чем вы запросили. Сколько именно, зависит от реализации, но вот пример:

struct MallocHeader {
    struct MallocHeader * prev, * next;
    size_t length;
    ... more data, padding, etc ...
    char data[0];
}

Когда malloc() выделяет память из свободного списка, он выделит size + sizeof(struct MallocHeader) и вернет адрес data. В free() смещение data в struct MallocHeader вычитается из переданного указателя, после чего становится известен размер.

2
ответ дан 8 December 2019 в 18:32
поделиться

Это зависит от реализации - это зависит от реализации libc, а также от реализации операционной системы (подробнее о реализации операционной системы).

У меня нет необходимости знать такие вещи, но если вы действительно хотите, вы можете создать свой собственный распределитель памяти.

По ошибке я обнаружил, что в C++ при выделении с помощью оператора new[] хранится количество элементов в начале выделяемой зоны, возвращая пользователю зону после количества элементов (На Visual Studio).

new[NUMBER] ---> [NUMBER (4bytes)]+[allocated area]
it returns the pointer to the allocated area
and probably when the delete[] operator is called
it looks 4 bytes before the [allocated area] to see
how much elements will be deleted
0
ответ дан 8 December 2019 в 18:32
поделиться

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

3
ответ дан 8 December 2019 в 18:32
поделиться
Другие вопросы по тегам:

Похожие вопросы: