Нет необходимости использовать нестандартные функции, нетрудно написать собственный распределитель с необходимой функциональностью.
Вы должны знать размер при выделении блока, поэтому просто сохраните эту информацию. Существует несколько ситуаций, когда IMO не знал бы эту информацию, поскольку по определению вы знали, когда она была распределена. Однако, если вам нужна такая функциональность, вы можете сделать это, просто обернув malloc () и предварительно ожидая размер блока.
void* smalloc( size_t size )
{
// allocate block with additional space for size
void* blk = malloc( size + sizeof(size_t) ) ;
// set the size
*((size_t*)blk) = size ;
// return pointer to block after size field (user block)
return ((size_t*)blk) + 1 ;
}
void sfree( const void* blk )
{
// Free from the size field address, not the user block
free( ((const size_t*)blk) - 1 ) ;
}
size_t ssize( const void* blk )
{
// Size is immediately before user block
return *(((size_t*)blk) - 1) ;
}
По мнению Джима Бака; На некоторых мишенях может потребоваться некоторое колебание, чтобы сохранить необходимое выравнивание. Некоторые цели будут генерировать менее эффективный код, если выравнивание не является оптимальным, другие вызовут прерывание. Так что остерегайтесь этого решения. Лично я опасаюсь необходимости такого решения!
Возможно, одним из решений было бы использование структуры данных, такой как хеш-таблица с адресом malloc в качестве ключа и размером в качестве содержимого, а также использование той же технологии оболочки для сохранения размера отдельно от блока - за счет или производительность, дополнительное хранилище и, возможно, некоторое ограничение емкости с точки зрения количества блоков, которыми можно управлять.
Как бы вы ни делали, фундаментальный пункт остается в силе - оберните базовый сервис, чтобы предоставить то, что вам нужно.