Хотя возможно получить метаданные, которые распределитель памяти размещает перед выделенным блоком, это будет работать только , если указатель действительно является указателем на динамически распределенный блок. Это серьезно повлияет на полезность функции, требующей, чтобы все передаваемые аргументы были указателями на такие блоки, а не простыми автоматическими или статическими массивами.
Дело в том, что нет портативного способа осмотра указателя узнать, на какой тип памяти он указывает. Так что, хотя это интересная идея, она не особенно безопасна.
Метод, который является безопасным и переносимым, состоит в том, чтобы зарезервировать первое слово распределения для хранения длины. GCC (и, возможно, некоторые другие компиляторы) поддерживает непереносимый метод реализации этого с использованием структуры с массивом нулевой длины, что несколько упрощает код по сравнению с переносимым решением:
typedef tSizedAlloc
{
size_t length ;
char* alloc[0] ; // Compiler specific extension!!!
} ;
// Allocating a sized block
tSizedAlloc* blk = malloc( sizeof(tSizedAlloc) + length ) ;
blk->length = length ;
// Accessing the size and data information of the block
size_t blk_length = blk->length ;
char* data = blk->alloc ;