Почему стандартная библиотека C не предоставляет функцию для определения размера выделенной памяти? - PullRequest
2 голосов
/ 02 мая 2020

Когда некоторый объем памяти динамически выделяется посредством вызова malloc(), ОС каким-то образом внутренне сохраняет объем выделенной памяти (для отслеживания используемой памяти и т. Д. c.), Поэтому мы предоставляем только указатель на free() когда нам больше не нужен этот кусок памяти.

Однако мы не можем получить этот размер, имея только указатель в переносимом и независимом от OS / компилятора виде. Существуют некоторые непереносимые способы, такие как _msize в Windows / Visual C или malloc_usable_size в glib c. Таким образом, единственный способ по-прежнему заключается в распространении всех необходимых размеров вместе с соответствующими указателями и т. Д. c., Что может быть очень подвержено ошибкам.

Итак, вопрос в том, почему стандартные разработчики C решили не включить переносимую функцию в стандарт?

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

Ответы [ 2 ]

5 голосов
/ 02 мая 2020

Поскольку вы можете получить указатели на вещи, которые не возвращаются от malloc и от друзей.

int x = 10;
int * p = &x;

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

int * p = malloc(sizeof(int) * 10);
int * p2 = p + 5;

Какой правильный результат, если я попрошу указать размер из p2?

Более последовательный подход предполагает передачу размеров по мере необходимости. Это позволяет вам работать с адресами независимо от того, откуда они пришли, включая смещения в некоторый блок памяти (например, массивы, как я делал с p2 выше).

4 голосов
/ 02 мая 2020

Нет технических проблем, мешающих стандартному комитету C добавить новую библиотечную функцию для получения числа байтов, доступных через действительный указатель, ранее возвращенный malloc(), calloc(), realloc(), aligned_alloc() , strdup() или любая аналогичная функция. Возвращаемое число не обязательно должно быть размером, первоначально переданным функции распределения, и возможно, что эта информация вообще может быть недоступна, поэтому возвращаемое значение 0 будет означать, что информация недоступна.

Причина, по которой такая функция еще не добавлена, может заключаться в том, что Комитет по стандартизации C обычно очень неохотно добавляет новые функции. Например, потребовалось более 30 лет, чтобы strdup() наконец добрался до стандарта C (он будет частью следующей версии), несмотря на то, что согласованные реализации были доступны в большинстве библиотек C на протяжении десятилетий.

Эта функция будет иметь неопределенное поведение для любого указателя, ранее не возвращенного функцией выделения памяти или уже освобожденного, как free или realloc. Является ли он определенным для NULL, является спорным, но возвращаемое значение 0 представляется уместным в этом случае. Если размер неизвестен, что возможно для фиктивных распределителей, которые не хранят эту информацию, возвращаемое значение 0 также будет указывать на это условие.

Вот реферат со страницы руководства malloc_usable_size присутствует в GNU lib C:

NAME

malloc_usable_size - получить размер блока памяти, выделенного из кучи

SYNOPSIS

   #include <malloc.h>

   size_t malloc_usable_size(void *ptr);

ОПИСАНИЕ

Функция malloc_usable_size() возвращает количество используемых байтов в блоке, на который указывает ptr указатель на блок памяти, выделенный с помощью malloc(3) или связанной функции.

ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ

malloc_usable_size() возвращает количество используемых байтов в блоке выделенной памяти, на которую указывает ptr. Если ptr равно NULL, возвращается 0.

АТРИБУТЫ

Многопоточность (см. pthreads(7)): функция malloc_usable_size() является потоковой safe.

СООТВЕТСТВУЕТ

Эта функция является расширением GNU.

ПРИМЕЧАНИЯ

Значение Возвращаемый malloc_usable_size() может быть больше, чем запрошенный размер выделения из-за ограничений выравнивания и минимального размера. Хотя избыточные байты могут быть перезаписаны приложением без негативных последствий, это не очень хорошая практика программирования: число избыточных байтов в выделении зависит от базовой реализации.

Основное использование этой функции - для отладки. и самоанализ.

СМОТРИ ТАКЖЕ

malloc(3)

...