Начинающий программист здесь. Это может быть нонсенс.
Я узнал о некоторых основах динамического распределения памяти с помощью malloc
и free
. Когда я выделяю память, для конкретности скажем, для массива из 10 ints
через malloc
, malloc
возвращает мне указатель p на начало выделенного блока памяти. Обычно я хотел бы передать этот указатель, а также некоторые соответствующие метаданные о выделении памяти (а именно, что это был массив длиной 10 int
s) в остальную часть моего кода для поддержки последующего информированного и безопасного чтения/записи. доступ. Именно это я и делаю, перемещая эти метаданные по своему коду.
Мне интересно, что когда приходит время действительно освобождать память, free
вполне способен выполнять эту работу, имея только указатель p; это не нужно говорить, например. длина массива. Я не знаю никаких подробностей здесь, но из того, что я прочитал, реализации malloc
/free
включают хранение и доступ к метаданным, которые записываются рядом с каждым распределением, и доступ к этим метаданным осуществляется free
в время освобождения (и, очевидно, достаточное, чтобы точно знать, какие ячейки памяти должны быть освобождены). Я предполагаю, что это должно означать, в частности, что в моем примере длина выделенного массива целых чисел может быть получена из метаданных, которые ищет free
.
Это приводит меня к нескольким вопросам:
Верны ли высокоуровневые подробности моего понимания существования этих метаданных?
Может ли программист, использующий стандартную библиотеку, получить доступ к этим метаданным распределения?
Если нет, можно ли легко получить к нему доступ из c средствами, отличными от стандартной библиотеки?
Если ответ на 2 или 3 отрицательный по причинам, связанным со стандартами и правилами, существуют ли конкретные контексты или примеры (например, которые работают только на определенной ОС или с определенной нестандартной реализацией c и т. д.), где это возможно и/или полезно?
Если это плохая идея, независимо от того, возможно ли это, мне было бы любопытно услышать, почему. Мое единственное предположение на данный момент заключается в том, что детали того, как хранятся метаданные, могут различаться в зависимости от системы, поэтому наивно использующий их код может оказаться нетерпимым к системным изменениям. Тем не менее, учитывая, что free может успешно использовать его в разных системах, я думаю, что будет способ инкапсулировать системные зависимости, чтобы по-прежнему получать полезный самоанализ метаданных.
Для 2 или 3 я представляю что-то вроде:
// Allocate some memory
int size = 10;
int *arr;
arr = (int *)malloc(sizeof(int) * size)
// Do other stuff.
// Choose not to keep track of storage details necessary for informed read/write access to arr, e.g. size;
// Acquire access to whatever `free` would access if asked to free `arr`
_type_ metadata = get_pointer_metadata(arr);
// Use metadata to perform read/writes
Но не знаете, есть ли что-то вроде get_pointer_metadata
в стандартной библиотеке c или в сторонних пакетах?
Я пробовал искать в Google такую функцию, но мое понимание деталей ситуации и языка слишком плохое, чтобы делать осмысленные поиски.
🤔 А знаете ли вы, что...
C имеет низкоуровневый характер, что позволяет разработчикам более точно управлять ресурсами компьютера.
Возможно/рекомендуется ли доступ к метаданным, хранящимся в malloc, через стандартную библиотеку?
Нет. Стандартная библиотека C не предлагает такого доступа.
Метаданные существуют, но то, где и что существует, более разнообразно. Метаданные могут быть закодированы в самом указателе. Исходный размер выделения может не существовать.
Нет.
Возможно. Некоторые компиляторы/библиотеки предлагают такой доступ. Это зависит от реализации.
Да, есть конкретные примеры. Поскольку я кодирую для переносимости, я не использую их, а вместо этого сам код отслеживает соответствующие метаданные.
Идея не столько плохая, сколько слабая.
Метаданные часто зависят от реализации, и поэтому, если бы библиотека требовала доступа к ним, это заставляло бы реализацию следовать ограничительной модели памяти.
Вместо того, чтобы внедрять конкретные решения, рассмотрите возможность создания структуры с вашими метаданными и передачи ее.
typedef struct {
void *ptr;
size_t size;
} ptr_sz;