В общем, нет.C не предоставляет способ получить размер выделенного блока памяти.Вам нужно следить за тем, сколько памяти вы выделили самостоятельно.
НО , в некоторых библиотеках C есть функция для получения полезного размера блока памяти - malloc_usable_size (находится в <malloc.h>
в системах Linux, без man-страницы).Обратите внимание, что это работает не для всех библиотек libcs и может сообщать о значении, превышающем запрашиваемое вами.Пожалуйста, используйте его только для отладки.
Для полноты моего оригинального ответа, который погружается в низкоуровневые метаданные кучи, перед @Employed Russian, указывающим malloc_usable_size
:
НО , вы можете извлечь это вручную.Обратите внимание, однако, что все это может варьироваться в зависимости от вашей ОС, архитектуры процессора и библиотеки C.Я предполагаю, что вы используете eglibc 2.12.1;ваши результаты могут отличаться где-либо еще.
ПРЕДУПРЕЖДЕНИЕ : Серьезно, НЕ используйте это, кроме как для отладки в GDB.В самом деле.Я имею в виду.
Распределитель памяти glibc хранит такие фрагменты памяти (из комментария к документу в malloc / malloc.c ):
chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Size of previous chunk, if allocated | |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Size of chunk, in bytes |M|P|
mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| User data starts here... .
. .
. (malloc_usable_size() bytes) .
. |
nextchunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Size of chunk |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Вашданные находятся в 'mem' здесь, и размер чанка включает заголовок.Флаг P указывает, являются ли данные предыдущего блока действительными, а M указывает, что это отображение mmap (для больших malloc).Все это не так важно;важно то, что размер живет на один шаг размера указателя перед вашей памятью;вам просто нужно замаскировать эти флаги и вычесть размер заголовка:
Breakpoint 1, main () at test.c:8
8 char *a = malloc(32);
(gdb) n
10 free(a);
(gdb) print (*((unsigned long long*)a - 1) & ~3) - sizeof(unsigned long long)*2
$14 = 32
Предупреждение: фактически выделенный размер может быть больше, чем вы запрашивали.Не пытайтесь стать умным и использовать лишнее.Спросите, сколько вам нужно в начале.
Предостережение 2: Это работает только с glibc.И это работает только с определенными версиями glibc.и, следовательно, может сломаться в любой момент без предупреждения.Я не могу подчеркнуть это достаточно; НЕ используйте это в вашем реальном коде;только для отладки, когда вы исчерпали все остальные опции.Ваш код должен самостоятельно отслеживать размеры буфера.