Любая функция для запроса размера выделенного блока?

Я понимаю, что любая такая функция, скорее всего, будет нестандартной, но для моего случая это нормально. По сути, мне нужен метод (даже если он предоставляется только через интерфейс syscall () glibc), на который я могу передать указатель (указатель, который был возвращен предыдущим вызовом malloc ()), который возвращает размер блока указателя указывает на. Такое существует?


person dicroce    schedule 15.09.2009    source источник


Ответы (3)


Насколько я знаю, по крайней мере в C90 / C99 такой функции нет. Некоторые системы, в основном libc, предоставляют функции для получения выделенного размера (например, malloc_size () в Mac OS X), но это не переносимо, и, вероятно, вам следует избегать его использования в лучшем случае.

person user172818    schedule 15.09.2009

Нет необходимости использовать нестандартные функции, нетрудно написать собственный аллокатор с нужным функционалом.

Вы должны знать размер при выделении блока, поэтому просто сохраните эту информацию. ИМО, есть несколько ситуаций, когда вы не знали бы эту информацию, поскольку по определению вы знали ее, когда она была размещена. Однако, если вам нужна такая функциональность, вы можете сделать это, просто обернув 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 в качестве ключа и размером в качестве содержимого, и с использованием той же техники оболочки хранить размер отдельно от блока - за счет или за счет производительности, дополнительное хранилище и, возможно, некоторый конечный предел емкости с точки зрения количества управляемых блоков.

Как бы вы это ни делали, основной момент остается в силе - оберните базовую услугу, чтобы предоставить то, что вам нужно.

person Clifford    schedule 15.09.2009
comment
Я отмечаю, что это более или менее идентично решению Эмиля Х, приведенному во второй ссылке в комментарии dmckee к исходному вопросу. Однако, как закомментированный код, возможно, он все еще имеет достоинства, поэтому я оставлю его в силе. - person Clifford; 15.09.2009
comment
Это нарушает любые гарантии выравнивания, которые в противном случае malloc мог бы дать вам на конкретной платформе. Если, например, вы работаете на платформе, которая гарантирует 8-байтовое выравнивание, этот пример кода теперь превращает его в 4-байтовое выравнивание. - person Jim Buck; 15.09.2009
comment
Согласованный. Дополнительное примечание добавлено по этой проблеме. - person Clifford; 15.09.2009

_msize на платформах Windows.

person Jim Buck    schedule 15.09.2009