c++ Узнать размер выделенного блока памяти

Dmitriy82

Есть ли способ определить размер блока памяти, выделенного
new Type[size]?
Единственное, что имеется - указатель на этот блок. По логике
это должно быть возможно, т.к. это делает delete, но предусмотрено ли?

Werdna

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

stm7583298

Я бы попробовал генерировать и отлавливать исключение при выходе за пределы массива, и шагать по нему

psihodog

Не факт, что аллокатор запоминает размер выделенного блока.
Я то же самое сначала подумал, но delete[] ведь будет убивать объекты из массива? А как он это сделает на зная количество и смещение каждого следующего (т.е. размер)?

enochka1145

size * sizeof(Type) ?

stm7583298

Есть у меня ощущение, пока MSDN-ом не подтвержденное, что delete[] просто уничтожает указатель, не трогая самих данных.
С другой стороны, была же в C функция realloc, которая должна была откуда-то брать старый размер

Dmitriy82

Не то чтобы мне это очень надо. Просто задумался как поизящнее написать, а вообще в моём случае можно просто переменную рядом держать с размером, или vector<> использовать.
Что ж, отрицательный результат (невозможность сделать это в соотв. со стандартом) - тоже результат.
Спасибо.

Werdna


Я бы попробовал генерировать и отлавливать исключение при выходе за пределы массива, и шагать по нему

Ты что, псих?

Werdna

пока MSDN-ом не подтвержденное

MSDN стал Библией? Это же ахтунг, говорить о плюсах и ссылаться на MSDN.

psihodog

Есть у меня ощущение, пока MSDN-ом не подтвержденное, что delete[] просто уничтожает указатель, не трогая самих данных.
Ещё бы оно подтвердилось!

Werdna

в моём случае можно просто переменную рядом держать с размером, или vector<> использовать.

Конечно же второе! Зачем изобретать велик?
Хотя может быть в твоей случае лучше map/hash_map?

Olyalyau

Есть у меня ощущение, пока MSDN-ом не подтвержденное, что delete[] просто уничтожает указатель, не трогая самих данных.

По стандарту delete [] вызывает деструктор для каждого элемента (если десктруктор не выкинет исключения, иначе -- unspecified behavior).
С другой стороны, была же в C функция realloc, которая должна была откуда-то брать старый размер

Где хранится размер -- зависит от реализации malloc'а. В ГНУтом malloc'е размер хранится в выделенном блоке до пользовательской части. (Точнее там размер не хранится, хранятся два указателя на смежные блоки, размер вычисляется арифметически из адреса блока и указателя на следующий; плюс к тому, в младшем бите указателей хранятся дополнительные флаги -- указатели выровнены). То есть при выделении памяти реально выделяется блок, больше запрашиваемого, в его начало кладутся два указателя | флаги, а пользователю возвращается указатель = (char *) указатель на блок + 2*sizeof (char *).
Встречаются malloc'и которые хранят размер или что ещё в других местах и не хранят вовсе (точнее хранят, например, в константе или дефайне и выделяют блоки всегда одного размера).

Realist

(если десктруктор не выкинет исключения, иначе -- unspecified behavior).
АФАИК, все-таки функция terminated вызывается, или какая-то такая

Werdna

если десктруктор не выкинет исключения

Руки бы отрывал пидорасам, которые могут подумать о том, чтобы в деструкторе исключение кинуть.

kokoc88

А ведь могут и не подумать. Напишут что-то типа m_...ReleaseResources; а оттуда исключение полетит.

Werdna

Напишут что-то типа m_...ReleaseResources;

Ну это надо понимать что-то из области Микрософта?

psihodog

Ну это надо понимать что-то из области Микрософта?
Почему? просто решил память освободить, или файл закрыть, а тут раз -- исключение.

Werdna

Деструктор не должен делать ничего, что может привести к исключению.
Освобождение памяти никогда еще не кидало исключений, только выделение. (А не как в микрософте, 0 возвращает)
вообще, в декларации надо писать virtual и throw всегда.

kokoc88

Деструктор не должен делать ничего, что может привести к исключению.
Должен или не должен - это одно. А что может - другое.
PS Майкрософт тут не при чём, а на open source код уже насмотрелись: ни одного нормально сделанного проекта, одни крики и пальцы.

evgen5555

нету throw в мсвц в объявлениях функций

psihodog

Освобождение памяти никогда еще не кидало исключений, только выделение.
А что случится, если попытаешься освободить что-нть не то? Программа вылетит? Это типа лучше?

Werdna


нету throw в мсвц в объявлениях функций

Т. е. нельзя написать "virtual ~classname throw;"?

kokoc88

Да можно, и написано.
	~CAtlArray throw;  

noss

Я использовал такую функцию
_msize_dbg(*p, _NORMAL_BLOCK)
возвращает размер в байтах

Dasar

> Т. е. нельзя написать "virtual ~classname throw;"?
допустим ты это напишешь, и что дальше?
чем это тебе поможет от следующего кода?

virtual ~ResourceHolder throw
{
void * buffer = 0;
delete buffer;
}

Werdna


virtual ~ResourceHolder throw
{
void * buffer = 0;
delete buffer;
}

а тут вообще undefined beheiver. На некоторых системах этот код вообще может на ура проработать.
Короче, к исключениям это не относится.

erotic


#include <malloc.h>
_msize(*p);
Returns the size of a memory block allocated in the heap.

Возвращает размер в байтах.

Werdna

В манах ничего такого нет, значит это не POSIX-стандартно!

erotic

А вдруг завтра это станет стандартом, значит, сегодня ты потерял возможность соответствовать стандарту в будущем
Оставить комментарий
Имя или ник:
Комментарий: