размер блока памяти выделяемой по 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 передается через член класса, что, мне кажется, не хорошо, поскольку он, этот член класса, служит только как средство подобной передачи параметра и ничего более.
Какое может быть решение? Я не очень понимаю как можно использовать вектор в этом случае...
Не выпендриваться, оставить все как есть?
Re[6]: размер блока памяти выделяемой по new
От: Nose Россия  
Дата: 14.04.05 07:40
Оценка:
Здравствуйте, Ellin, Вы писали:

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


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


E>Потом operator delete или new перегрузишь (лет через 10 кодинга или твой коллега), знаешь сколько ошибок словить можно будет? Да дурно это, какая-то не здоровая весчь.


Все еще хуже. Насколько я понимаю, размер выделенной памяти может храниться по-разному для разных компиляторов.
Re[4]: размер блока памяти выделяемой по new
От: Кодт Россия  
Дата: 14.04.05 07:57
Оценка:
Здравствуйте, Murom, Вы писали:

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

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

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


M>Про библиотеку CRT можно говорить только применительно к конкретной реализации конкретным производителем для конкретной платформы.

M>Знание библиотеки не дает даже надежды, что при портировании кода даже не другую операционку, а под другую версию компилятора, Вы не наступите на грабли.

Если не заниматься хаками, то надежда будет оправдана.

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


Упоминание — это к тому, чтобы не пользоваться CRT'шными функциями типа _msize() (MS-specific) и т.п.

M>Из примера
int *p = new int[5];
можно сказать, что ты получишь не меньше 5 элементов типа int, если p не нулевой.


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

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



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


К>Упоминание — это к тому, чтобы не пользоваться CRT'шными функциями типа _msize() (MS-specific) и т.п.


Честно говоря, сначало было желание воспользоваться _msize... но вы так настойчиво отговариваете...

Николай, а какой контейнер вы посоветуете в связи со следующим:

Пусть:

p = new char[lFileLength];



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

Я не очень хорошо знаю STL сейчас буду читать MSDN про <new> и <memory>
Re[5]: размер блока памяти выделяемой по new
От: Кодт Россия  
Дата: 14.04.05 08:51
Оценка:
Здравствуйте, df, Вы писали:

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


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

df>В качестве подтверждения:

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


df>как вам такое, а? Вот то-то... Есть и другая жуть...

df>Ладно это все лирика... Далее если коротко так:

df>
df>p = new char[lFileLength];
df>


df>далее этот р передается в функцию (пусть будет FNet()) в которой работает NetAgent. Он принимает этот указатель вкачестве параметра и отправляет данные, скажем, на сервер. Так же для работы Нетагенту нужна lFileLength. FNet() исполняется в потоке, поэтому сделано так, что она принимает this в качестве параметра.

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

Как мрачно... А просто использовать строки (std::string, MFC CString) нельзя?
Перекуём баги на фичи!
Re[6]: размер блока памяти выделяемой по new
От: df Россия  
Дата: 14.04.05 09:18
Оценка:
Здравствуйте, Кодт, Вы писали:

Далее если коротко так:

df>>
df>>p = new char[lFileLength];
df>>


df>>далее этот р передается в функцию (пусть будет FNet()) в которой работает NetAgent. Он принимает этот указатель вкачестве параметра и отправляет данные, скажем, на сервер. Так же для работы Нетагенту нужна lFileLength. FNet() исполняется в потоке, поэтому сделано так, что она принимает this в качестве параметра.

df>> В проекте близнеце lFileLength передается через член класса, что, мне кажется, не хорошо, поскольку он, этот член класса, служит только как средство подобной передачи параметра и ничего более.

df>> Какое может быть решение? Я не очень понимаю как можно использовать вектор в этом случае...

df>> Не выпендриваться, оставить все как есть?

К>Как мрачно... А просто использовать строки (std::string, MFC CString) нельзя?


Да можно, наверное... но там ведь как:

FDescr=_open(LocalFileName, _O_BINARY|_O_RDONLY);
...
FLength=_filelength(FDescr);
...
pFileBuff=new char[FLength];
_read(FDescr, pFileBuff, FLength);
...


а далее см. выше, примерную существующую логику я описал...

может все-таки calloc и _msize?
или контейнер <memory>... сейчас пытаюсь с ним разобраться...
или какой другой...
Re[7]: размер блока памяти выделяемой по new
От: Кодт Россия  
Дата: 14.04.05 09:33
Оценка:
Здравствуйте, df, Вы писали:

К>>Как мрачно... А просто использовать строки (std::string, MFC CString) нельзя?


df>Да можно, наверное... но там ведь как:


df>
df>FDescr=_open(LocalFileName, _O_BINARY|_O_RDONLY);
df>...
df>FLength=_filelength(FDescr);
df>...
df>pFileBuff=new char[FLength];
df>_read(FDescr, pFileBuff, FLength);
df>...
df>


df>а далее см. выше, примерную существующую логику я описал...


df>может все-таки calloc и _msize?


_msize возвращает не размер массива, а размер блока памяти, выданного под массив.
_msize(malloc(10)) > 10.

df>или контейнер <memory>... сейчас пытаюсь с ним разобраться...

df>или какой другой...

vector<char> ?
И передавай его по ссылке, чтобы копированием не заниматься без нужды.
Перекуём баги на фичи!
Re[3]: размер блока памяти выделяемой по new
От: Glоbus Украина  
Дата: 14.04.05 10:05
Оценка:
Здравствуйте, BacCM, Вы писали:

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


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


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

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

BCM>А еще лучше обернуть классом или исползовать чей нибудь готовый


например std::vector
Удачи тебе, браток!
Re[8]: размер блока памяти выделяемой по new
От: df Россия  
Дата: 14.04.05 10:11
Оценка:
Здравствуйте, Кодт, Вы писали:

К>>>Как мрачно...


К>vector<char> ?


Все здорово, вот только не углубляясь я не понял как мне файл-то туда, в вектор, прочитать??

df>> FDescr = _open(LocalFileName,      // имя файла (CString)
                   _O_BINARY|_O_RDONLY);
df>>...
df>> FLength = _filelength(FDescr);     // размер в байтах
df>>...
df>> pFileBuff=new char[FLength];       //    
df>> _read(FDescr, pFileBuff, FLength); // в созданный буфер прочитал файл
df>>...
Re[7]: размер блока памяти выделяемой по new
От: Glоbus Украина  
Дата: 14.04.05 10:13
Оценка:
Здравствуйте, df, Вы писали:

df>Да можно, наверное... но там ведь как:


df>
df>FDescr=_open(LocalFileName, _O_BINARY|_O_RDONLY);
df>...
df>FLength=_filelength(FDescr);
df>...
df>pFileBuff=new char[FLength];
df>_read(FDescr, pFileBuff, FLength);
df>...
df>


Наприме ртут моожно сделать одно маленькое упрощение. так как тебе размер заране известен — сколько выделить, то можно написать так

FDescr=_open(LocalFileName, _O_BINARY|_O_RDONLY);
...
FLength=_filelength(FDescr);
...
std::vector<char> FileBuff(FLength); 
FileBuff.resize( FLength ); //застолбили память
_read(FDescr, &FileBuff[0], FLength); //так как элементы вектора расположены неприрывно, то можно получить адрес начала блока памяти
...


Ну а дальше уже вместо указателя на массив можно например передавать ссылку на этот вектор — конечно код, который эти указатели пользовал раньше придется малось подправить
Удачи тебе, браток!
Re[9]: размер блока памяти выделяемой по new
От: Кодт Россия  
Дата: 14.04.05 10:23
Оценка:
Здравствуйте, df, Вы писали:

К>>vector<char> ?


df>Все здорово, вот только не углубляясь я не понял как мне файл-то туда, в вектор, прочитать??


vector<char> filebuf;
...
filebuf.resize(FLength); // или прямо в конструкторе указать
_read(FDescr, &filebuf[0], FLength);
Перекуём баги на фичи!
Re[8]: размер блока памяти выделяемой по new
От: df Россия  
Дата: 14.04.05 10:37
Оценка:
Здравствуйте, Glоbus, Вы писали:


G>FDescr=_open(LocalFileName, _O_BINARY|_O_RDONLY);
G>...
G>FLength=_filelength(FDescr);
G>...
G>std::vector<char> FileBuff(FLength); 
G>FileBuff.resize( FLength ); //застолбили память
G>_read(FDescr, &FileBuff[0], FLength); //так как элементы вектора расположены неприрывно, то можно получить адрес начала блока памяти
G>...


G> — конечно код, который эти указатели пользовал раньше придется малось подправить :)



G>_read(FDescr, &FileBuff[0], FLength); //_если это сработает - будет гуд!_



std::vector<char> FileBuff(FLength);
А после _такого_ создания вектор обязательно ресайзить нужно? Разве память не выделяется сразу? Зачем тогда размер указываем?
В msdn об этом ничего не нашел :shuffle:
Re[10]: размер блока памяти выделяемой по new
От: df Россия  
Дата: 14.04.05 10:41
Оценка:
Здравствуйте, Кодт, Вы писали:

К>
К>vector<char> filebuf;
К>...
К>filebuf.resize(FLength); // или прямо в конструкторе указать
К>_read(FDescr, &filebuf[0], FLength);
К>



Большое спасибо!
Пошу прощения за свою темноту !
Re[3]: размер блока памяти выделяемой по new
От: ansi  
Дата: 14.04.05 12:11
Оценка:
Здравствуйте, BacCM, Вы писали:

BCM>А еще лучше обернуть классом или исползовать чей нибудь готовый

Начинается... Почему лучше?
new RSDN@Home(1.1.4, 303) << new Message(); std::head::ear << "Mohicans — A New Day";
Re[4]: размер блока памяти выделяемой по new
От: Кодт Россия  
Дата: 14.04.05 13:00
Оценка: 2 (2) +2
Здравствуйте, ansi, Вы писали:

BCM>>А еще лучше обернуть классом или исползовать чей нибудь готовый

A>Начинается... Почему лучше?

Потому что так в программе разделяются уровни функционирования. Все задачи, скажем, по управлению блоком памяти — сосредоточены в классе my_block_of_memory, а задачи использования этой памяти — в клиентском коде.
Иначе есть огромное искушение проинлайнить этот низкоуровневый код руками. А через дельта-тэ мы имеем не программу, а спагетти.

Эволюция работы с динамическими объектами выглядит примерно так:

1) В пределах одного объекта или одной функции: создали, поковыряли, удалили
2) Создали; передали в функцию {там поковыряли}; удалили
3) Создали; поковыряли; отдали в функцию [запомнили: она владеет] {там ещё попередавали и удалили}
4) Изобрели велосипед по контролю владения; создали, инициализировали владение; передали в функцию; чего-то забыли, владение расщепилось; дважды удалили, UB.
5) Исправили, всюду по коду расставили проверки — через месяц смотришь: а что это здесь понаписано?
6) Решили чуток переделать управление объектом; еле-еле нашли все вхождения, творчески переработали, накосячили, упало.
7) Исправили косяки, всё работает, ан нет — в дальнем углу ещё с п.5 чего-то осталось, а то и с п.3.
Перекуём баги на фичи!
Re[5]: размер блока памяти выделяемой по new
От: BacCM Россия  
Дата: 15.04.05 06:43
Оценка:
Здравствуйте, Кодт, Вы писали:


К>Эволюция работы с динамическими объектами выглядит примерно так:


Классно описано
... << RSDN@Home 1.1.4 beta 4 rev. 388>>
Re[5]: размер блока памяти выделяемой по new
От: ansi  
Дата: 15.04.05 13:21
Оценка:
Здравствуйте, Кодт, Вы писали:

BCM>>>А еще лучше обернуть классом или исползовать чей нибудь готовый

A>>Начинается... Почему лучше?

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

К>Иначе есть огромное искушение проинлайнить этот низкоуровневый код руками. А через дельта-тэ мы имеем не программу, а спагетти.

К>Эволюция работы с динамическими объектами выглядит примерно так:


К>1) В пределах одного объекта или одной функции: создали, поковыряли, удалили

К>2) Создали; передали в функцию {там поковыряли}; удалили
К>3) Создали; поковыряли; отдали в функцию [запомнили: она владеет] {там ещё попередавали и удалили}
К>4) Изобрели велосипед по контролю владения; создали, инициализировали владение; передали в функцию; чего-то забыли, владение расщепилось; дважды удалили, UB.
К>5) Исправили, всюду по коду расставили проверки — через месяц смотришь: а что это здесь понаписано?
К>6) Решили чуток переделать управление объектом; еле-еле нашли все вхождения, творчески переработали, накосячили, упало.
К>7) Исправили косяки, всё работает, ан нет — в дальнем углу ещё с п.5 чего-то осталось, а то и с п.3.

Эволюция забавная конечно, но реально это дело должно учитываться еще при проектиронии. У нас вот 300 Мб исходников и все на Си... Проблем с управлением памятью, ну не то, чтобы не было, но я видел только один баг, связанный с утечкой. Вобщем все четко регламентировано, кто, что и куда передает и кто, где и когда освобождает.
Я в принципе не говорю, что обертками не надо пользоваться, просто не стоит, на мой взгляд, в крайности бросаться и совать их, где им не самое место. В принципе, работа с памятью очевидна, а реализация обертки...кто его знает.
new RSDN@Home(1.1.4, 303) << new Message(); std::head::ear << "Celtic Angels — Angels Sea";
Re[5]: размер блока памяти выделяемой по new
От: lastique  
Дата: 15.04.05 20:31
Оценка:
df>Ладно это все лирика... Далее если коротко так:

df>
df>p = new char[lFileLength];
df>


df>далее этот р передается в функцию (пусть будет FNet()) в которой работает NetAgent. Он принимает этот указатель вкачестве параметра и отправляет данные, скажем, на сервер. Так же для работы Нетагенту нужна lFileLength. FNet() исполняется в потоке, поэтому сделано так, что она принимает this в качестве параметра.

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


Если код совсем мрачный и трогать его совсем не хочется, то можно предложить решение а-ля BSTR. Т.е. типа такого:
size_t lFileLength = ...;
p = new char[lFileLength + sizeof(size_t)];
*(reinterpret_cast< size_t* >(p)) = lFileLength;
Foo(p);


А в Foo() написать типа этого:
void Foo(char* _p) {
 size_t Size = *(reinterpret_cast< size_t* >(p));
 char* p = _p + sizeof(size_t);
 // Далее пользуем p как и раньше без изменений
}


Решение не очень хорошее, но иногда самое простое.
Re: размер блока памяти выделяемой по new
От: Chez Россия  
Дата: 18.04.05 14:09
Оценка:

_msize
Returns the size of a memory block allocated in the heap.

size_t _msize( void *memblock );
Parameter
— memblock
Pointer to memory block
Libraries
All versions of the C run-time libraries.

Return Value
_msize returns the size (in bytes) as an unsigned integer.

Remarks
The _msize function returns the size, in bytes, of the memory block allocated by a call to malloc, or realloc.

When the application is linked with a debug version of the C run-time libraries, _msize resolves to _msize_dbg. For more information about how the heap is managed during the debugging process, see Using C Run-Time Library Debugging Support.

Chez, ICQ#161095094

Posted via:RSDN@Home;version:1.1.3;muzikstamp:silent

Re[2]: размер блока памяти выделяемой по new
От: Кодт Россия  
Дата: 18.04.05 16:36
Оценка:
Здравствуйте, Chez, Вы писали:

C>Remarks

C>The _msize function returns the size, in bytes, of the memory block allocated by a call to malloc, or realloc.

Обрати внимание: size of the block allocated by a call. Но не сказано, что размер этого блока равен заказанному размеру.

Об этом же говорится в справке по malloc

Allocates memory blocks.

void *malloc(
   size_t size 
);

Parameter
size
Bytes to allocate.

Return Value
malloc returns a void pointer to the allocated space, or NULL if there is insufficient memory available. To return a pointer to a type other than void, use a type cast on the return value. The storage space pointed to by the return value is guaranteed to be suitably aligned for storage of any type of object. If size is 0, malloc allocates a zero-length item in the heap and returns a valid pointer to that item. Always check the return from malloc, even if the amount of memory requested is small.

Remarks
The malloc function allocates a memory block of at least size bytes. The block may be larger than size bytes because of space required for alignment and maintenance information.

Перекуём баги на фичи!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.