размер блока памяти выделяемой по new
От: df Россия  
Дата: 13.04.05 13:55
Оценка:
Добрый день!

Подскажите пожалуйста, существуют-ли способы узнать размер блока памяти выделяемой оператором new?
Т.е. например


int *p = new int[5];


можно-ли узнать, что теперь скрывается за p? Если я передаю в функцию этот указатель, то могу-ли я узнать размер блока памяти на который указывает p?
Re: размер блока памяти выделяемой по new
От: korzhik Россия  
Дата: 13.04.05 14:06
Оценка:
Здравствуйте, df, Вы писали:

df>Добрый день!


df>Подскажите пожалуйста, существуют-ли способы узнать размер блока памяти выделяемой оператором new?

df>Т.е. например

df>

df>int *p = new int[5];

df>


df>можно-ли узнать, что теперь скрывается за p? Если я передаю в функцию этот указатель, то могу-ли я узнать размер блока памяти на который указывает p?


нет нельзя.
Вместе с указателем надо передавать размер
Re[2]: размер блока памяти выделяемой по new
От: BacCM Россия  
Дата: 13.04.05 14:09
Оценка:
Здравствуйте, korzhik, Вы писали:

df>>можно-ли узнать, что теперь скрывается за p? Если я передаю в функцию этот указатель, то могу-ли я узнать размер блока памяти на который указывает p?


K>нет нельзя.

K>Вместе с указателем надо передавать размер

А еще лучше обернуть классом или исползовать чей нибудь готовый
... << RSDN@Home 1.1.4 beta 4 rev. 388>>
Re: размер блока памяти выделяемой по new
От: Нахлобуч Великобритания https://hglabhq.com
Дата: 13.04.05 14:09
Оценка: 1 (1) +2
Здравствуйте, df, Вы писали:

df>можно-ли узнать, что теперь скрывается за p? Если я передаю в функцию этот указатель, то могу-ли я узнать размер блока памяти на который указывает p?


Ну как бы это... Теоретически — да (имхо). Библиотеке CRT надо знать, сколько памяти она выделила, чтобы потом все корректно освободить. Соответственно, эту служебную информацию надо где-то хранить. Есть два подхода. Первый — это где-то во внутренних служебных структурах CRT, а второй — перед выделенным блоком по адресу (примерно так):
(char *)p - sizeof(size_t)
HgLab: Mercurial Server and Repository Management for Windows
Re[2]: размер блока памяти выделяемой по new
От: df Россия  
Дата: 13.04.05 14:15
Оценка:
Здравствуйте, korzhik, Вы писали:



df>>Подскажите пожалуйста, существуют-ли способы узнать размер блока памяти выделяемой оператором new?

df>>Т.е. например

df>>

df>>int *p = new int[5];

df>>


df>>можно-ли узнать, что теперь скрывается за p? Если я передаю в функцию этот указатель, то могу-ли я узнать размер блока памяти на который указывает p?


K>нет нельзя.


Категорически?

А как delete[] p; работает? Он-то как-то узнает размер блока, или для программиста это криминал?

K>Вместе с указателем надо передавать размер

Эт да.
Re[3]: размер блока памяти выделяемой по new
От: Вадим Никулин Россия Здесь
Дата: 13.04.05 14:18
Оценка: 1 (1)
Здравствуйте, df, Вы писали:

df>>>можно-ли узнать, что теперь скрывается за p? Если я передаю в функцию этот указатель, то могу-ли я узнать размер блока памяти на который указывает p?


K>>нет нельзя.


df>Категорически?


df>А как delete[] p; работает? Он-то как-то узнает размер блока, или для программиста это криминал?

Криминал. Зато не является криминалом использование std::vector
Re[2]: размер блока памяти выделяемой по new
От: df Россия  
Дата: 13.04.05 14:24
Оценка:
Здравствуйте, Нахлобуч, Вы писали:

Н>Здравствуйте, df, Вы писали:


df>>можно-ли узнать, что теперь скрывается за p? Если я передаю в функцию этот указатель, то могу-ли я узнать размер блока памяти на который указывает p?


Н>Ну как бы это... Теоретически — да (имхо). Библиотеке CRT надо знать, сколько памяти она выделила, чтобы потом все корректно освободить.


Однозначно, надо знать. Вопрос в том возможно-ли это использовать (как delete[]) или это порочный путь.

Вопрос между тем, не совсем праздный. Ковыряюсь в старом проекте, который писался много лет, многими людьми, там такое понаворочено, что не хочется переделывать функции (в плане передачи параметров) ибо это за собой много чего тянет
Re[2]: размер блока памяти выделяемой по new
От: Кодт Россия  
Дата: 13.04.05 14:26
Оценка: 1 (1) +1
Здравствуйте, Нахлобуч, Вы писали:

Н>Ну как бы это... Теоретически — да (имхо). Библиотеке CRT надо знать, сколько памяти она выделила, чтобы потом все корректно освободить. Соответственно, эту служебную информацию надо где-то хранить. Есть два подхода. Первый — это где-то во внутренних служебных структурах CRT, а второй — перед выделенным блоком по адресу (примерно так):

Н>
Н>(char *)p - sizeof(size_t)
Н>


Не забывайте, что у кучи есть гранулярность. То есть, попросил 4 байта, а она тебе вручила 16.
Впрочем, чтобы не зависеть от дефолтной кучи — можно написать свой менеджер памяти (перегрузить operator new, operator delete и похимичить с макросами).
Но инструкции new[]/delete[] (не операторы, а именно statement'ы) вдобавок к памяти, нужной для массива, подвёрстывают свою информацию о количестве элементов. Причём не всегда, а только если у типа есть нетривиальный деструктор.
Поэтому заниматься хаком и добывать размер массива обиняками — занятие бестолковое.

Лучше пользоваться обёртками массивов — тем же std::vector, например.
Перекуём баги на фичи!
Re[4]: размер блока памяти выделяемой по new
От: df Россия  
Дата: 13.04.05 14:29
Оценка:
Здравствуйте, Вадим Никулин, Вы писали:

ВН>Здравствуйте, df, Вы писали:


df>>>>можно-ли узнать, что теперь скрывается за p? Если я передаю в функцию этот указатель, то могу-ли я узнать размер блока памяти на который указывает p?




df>>А как delete[] p; работает? Он-то как-то узнает размер блока, или для программиста это криминал?

ВН>Криминал. Зато не является криминалом использование std::vector ;)

Предполагал я такие ответы, хотя грустно... как я уже отвечал человеку

"в старом проекте, который писался много лет, многими людьми, там такое понаворочено, что не хочется переделывать функции (в плане передачи параметров) ибо это за собой много чего тянет..."

ПС: а почему это криминал?
Re[3]: размер блока памяти выделяемой по new
От: Нахлобуч Великобритания https://hglabhq.com
Дата: 13.04.05 14:31
Оценка:
Здравствуйте, Кодт, Вы писали:

К>Но инструкции new[]/delete[] (не операторы, а именно statement'ы) вдобавок к памяти, нужной для массива, подвёрстывают свою информацию о количестве элементов. Причём не всегда, а только если у типа есть нетривиальный деструктор.


А можно определение "{не}тривиального деструктора"? Чтобы на будущее, так сказать...
HgLab: Mercurial Server and Repository Management for Windows
Re[3]: размер блока памяти выделяемой по new
От: df Россия  
Дата: 13.04.05 14:35
Оценка:
Здравствуйте, Кодт, Вы писали:



К>Не забывайте, что у кучи есть гранулярность. То есть, попросил 4 байта, а она тебе вручила 16.

К>Впрочем, чтобы не зависеть от дефолтной кучи — можно написать свой менеджер памяти (перегрузить operator new, operator delete и похимичить с макросами).
К>Но инструкции new[]/delete[] (не операторы, а именно statement'ы) вдобавок к памяти, нужной для массива, подвёрстывают свою информацию о количестве элементов. Причём не всегда, а только если у типа есть нетривиальный деструктор.
К>Поэтому заниматься хаком и добывать размер массива обиняками — занятие бестолковое.

Все.... похоронили....
Ok, а если простые типы: char, int? все равно никак?

К>Лучше пользоваться обёртками массивов — тем же std::vector, например.


Лучше, но все уже написано до меня. Мне нужно только кое-чего изменить, отсюда соблазн минимизировать....
Re[4]: размер блока памяти выделяемой по new
От: Кодт Россия  
Дата: 13.04.05 14:38
Оценка:
Здравствуйте, Нахлобуч, Вы писали:

Н>А можно определение "{не}тривиального деструктора"? Чтобы на будущее, так сказать...


Стандарт (12.4.3)
Деструктор тривиальный, если
— он неявный (т.е. нет объявления); в частности, у всех POD-типов деструкторы тривиальные
— и у всех членов и баз тривиальные деструкторы

Т.е., если в деструкторе проводится какая-то работа (пусть даже {}) — он нетривиальный.
Перекуём баги на фичи!
Re[4]: размер блока памяти выделяемой по new
От: Bell Россия  
Дата: 13.04.05 14:40
Оценка:
Здравствуйте, Нахлобуч, Вы писали:

Н>А можно определение "{не}тривиального деструктора"? Чтобы на будущее, так сказать...


Да пожалуйста:
12.4
...

3 If a class has no user declared
destructor, a destructor is declared implicitly. An implicitly declared
destructor is an inline public member of its class. A destructor is 
trivial if it is an implicitlydeclared destructor and if:
— all of the direct base classes of its class have trivial destructors and
— for all of the nonstatic data members of its class that are of class type 
(or array thereof), each such class has a trivial destructor.

4 Otherwise, the destructor is nontrivial.

...
Любите книгу — источник знаний (с) М.Горький
Re[5]: размер блока памяти выделяемой по new
От: Ellin Россия www.rsdn.ru
Дата: 13.04.05 14:41
Оценка:
Здравствуйте, df, Вы писали:

df>ПС: а почему это криминал?


Потом operator delete или new перегрузишь (лет через 10 кодинга или твой коллега), знаешь сколько ошибок словить можно будет? Да дурно это, какая-то не здоровая весчь.
... << RSDN@Home 1.1.4 beta 5 rev. 395>>
Re[3]: размер блока памяти выделяемой по new
От: df Россия  
Дата: 13.04.05 14:44
Оценка:
Здравствуйте, Кодт, Вы писали:


К>Но инструкции new[]/delete[] (не операторы, а именно statement'ы) вдобавок к памяти, нужной для массива, подвёрстывают свою информацию о количестве элементов. Причём не всегда, а только если у типа есть нетривиальный деструктор.


Кстати. Может узнать количество элементов будет вполне достаточно, тип известен, реально?


ПС: Спасибо всем за потраченное время
Re[4]: размер блока памяти выделяемой по new
От: Кодт Россия  
Дата: 13.04.05 14:50
Оценка:
Здравствуйте, df, Вы писали:

К>>Лучше пользоваться обёртками массивов — тем же std::vector, например.


df>Лучше, но все уже написано до меня. Мне нужно только кое-чего изменить, отсюда соблазн минимизировать....


Мышиная возня с голыми типами (в частности, с указателями) — обычно к добру не приводит.
В лучшем случае оттягиваешь рефакторинг... особенно, если проект большой.

Можно выполнить "кровавый рефакторинг", заменив голый указатель умным. Компилятор быстро покажет, где фигурируют твои типы — один день потеряешь, зато потом за час долетишь.
Перекуём баги на фичи!
Re[5]: размер блока памяти выделяемой по new
От: df Россия  
Дата: 13.04.05 15:00
Оценка:
Здравствуйте, Кодт, Вы писали:

К>Здравствуйте, df, Вы писали:


К>>>Лучше пользоваться обёртками массивов — тем же std::vector, например.


df>>Лучше, но все уже написано до меня. Мне нужно только кое-чего изменить, отсюда соблазн минимизировать....


К>Мышиная возня с голыми типами (в частности, с указателями) — обычно к добру не приводит.

К>В лучшем случае оттягиваешь рефакторинг... особенно, если проект большой.

К>Можно выполнить "кровавый рефакторинг", заменив голый указатель умным. Компилятор быстро покажет, где фигурируют твои типы — один день потеряешь, зато потом за час долетишь.


Как в воду глядишь Похоже все к этому и идет. А сейчас все на дирижаблей (концерт Роберта Планта в Питере через час)

Еще раз всем большое спасибо
Re[3]: размер блока памяти выделяемой по new
От: korzhik Россия  
Дата: 13.04.05 18:10
Оценка:
Здравствуйте, df, Вы писали:

df>Вопрос между тем, не совсем праздный. Ковыряюсь в старом проекте, который писался много лет, многими людьми, там такое понаворочено, что не хочется переделывать функции (в плане передачи параметров) ибо это за собой много чего тянет


Показывай код, рассказывай в чём проблема, может чего придумаем коллективным разумом.
Re[3]: размер блока памяти выделяемой по new
От: Murom Россия  
Дата: 14.04.05 04:55
Оценка:
Здравствуйте, Кодт, Вы писали:

К>Здравствуйте, Нахлобуч, Вы писали:


Н>>Ну как бы это... Теоретически — да (имхо). Библиотеке CRT надо знать, сколько памяти она выделила, чтобы потом все корректно освободить. Соответственно, эту служебную информацию надо где-то хранить. Есть два подхода. Первый — это где-то во внутренних служебных структурах CRT, а второй — перед выделенным блоком по адресу (примерно так):

Н>>
Н>>(char *)p - sizeof(size_t)
Н>>


К>Не забывайте, что у кучи есть гранулярность. То есть, попросил 4 байта, а она тебе вручила 16.

К>Впрочем, чтобы не зависеть от дефолтной кучи — можно написать свой менеджер памяти (перегрузить operator new, operator delete и похимичить с макросами).
К>Но инструкции new[]/delete[] (не операторы, а именно statement'ы) вдобавок к памяти, нужной для массива, подвёрстывают свою информацию о количестве элементов. Причём не всегда, а только если у типа есть нетривиальный деструктор.
К>Поэтому заниматься хаком и добывать размер массива обиняками — занятие бестолковое.

К>Лучше пользоваться обёртками массивов — тем же std::vector, например.


Про библиотеку CRT можно говорить только применительно к конкретной реализации конкретным производителем для конкретной платформы.
Знание библиотеки не дает даже надежды, что при портировании кода даже не другую операционку, а под другую версию компилятора, Вы не наступите на грабли.

Также язык С++ не обесчает, что оператор new выделит память на куче. Что если этой самой кучи вообще нет? И уж о гранулярности тем более вопрос настолько не корректный, что упоминания про 16 байт не имеет право на жизнь.

Из примера
int *p = new int[5];
можно сказать, что ты получишь не меньше 5 элементов типа int, если p не нулевой.
- Eugeny
Re[4]: размер блока памяти выделяемой по new
От: df Россия  
Дата: 14.04.05 07:29
Оценка:
Здравствуйте, korzhik, Вы писали:

K>Здравствуйте, df, Вы писали:


df>>Вопрос между тем, не совсем праздный. Ковыряюсь в старом проекте, который писался много лет, многими людьми, там такое понаворочено, что не хочется переделывать функции (в плане передачи параметров) ибо это за собой много чего тянет


K>Показывай код, рассказывай в чём проблема, может чего придумаем коллективным разумом.


Ну хорошо. Может в самом деле чего придумаем. Весь код показывать не имеет смысла, решит кто-нибудь, что это я такое понаписал, во век потом не отмоюсь. Стыдно и страшно там :(.
В качестве подтверждения:

int FDescr=_open(LocalFileName.operator LPCTSTR(), _O_BINARY|_O_RDONLY);
//               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^


как вам такое, а? Вот то-то... :( Есть и другая жуть...
Ладно это все лирика... Далее если коротко так:

p = new char[lFileLength];


далее этот р передается в функцию (пусть будет FNet()) в которой работает NetAgent. Он принимает этот указатель вкачестве параметра и отправляет данные, скажем, на сервер. Так же для работы Нетагенту нужна lFileLength. FNet() исполняется в потоке, поэтому сделано так, что она принимает this в качестве параметра.
В проекте близнеце lFileLength передается через член класса, что, мне кажется, не хорошо, поскольку он, этот член класса, служит только как средство подобной передачи параметра и ничего более.
Какое может быть решение? Я не очень понимаю как можно использовать вектор в этом случае...
Не выпендриваться, оставить все как есть?
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.