|
А почему так инициализация |
|
|
|
 |
Ответов
(60 - 74)
|
Jul 27 2018, 07:44
|

Профессионал
    
Группа: Свой
Сообщений: 1 215
Регистрация: 22-02-05
Пользователь №: 2 831

|
Цитата(DASM @ Jul 27 2018, 10:29)  i это не итератор, это локальная переменная типа элемента вектора. В моем компиляторе - это не просто int. Я это проверил: попытка присвоить содержимое этого i кому-нить еще (я пробовал простой массив int a[5]; ), приводит к копирования некого адреса где-то в ОЗУ, но вовсе не содержимого. Это видно в окне watch. Да и ходьба по шагам, где происходит обращение к i, кидает во внутренний некий файл iterator, где все это происходит. Короче, for() в этом компиляторе тут ни разу не for() как это в привычном C или старом C++03, а разворачивается в конструкцию по-сложнее: https://en.cppreference.com/w/cpp/language/range-for (см. раздел Explanation) По крайней мере, если речь идет про vector или что-то подобное.
--------------------
Кругозор некоторых людей - круг с нулевым радиусом. Они называют его "точкой зрения".
|
|
|
|
|
Jul 29 2018, 16:18
|

Профессионал
    
Группа: Свой
Сообщений: 1 215
Регистрация: 22-02-05
Пользователь №: 2 831

|
Заглумил я тут всех Короче, увеличил кучу, все стало работать правильно! Дело было в том, что куча у меня не используется и на нее выделяется от силы 16 байт. Тут этого было мало. Ради финальной проверки, инициализирую iv так: Код vector <int> iv = {1, 2, 3, 4, 5}; int trace[5]; int ix = 0; for (auto i : iv) { trace[ix++] = i; } И результат соответствующий: trace: 1, 2, 3, 4, 5.Получается, что все верно: при каждой итерации for (auto i : iv) вызывается оператор копирования из вектора iv, а результат кладется в i, которая все верно - обычная int (проверил через sizeof) Имхо, это несколько непривычно для восприятия цикла for, ведь "i" тут - вовсе не индекс для перебора внутри вектора, а лишь копия одного из его элементов, или по-другому - результат, возвращаемый внутренним итератором (в данном цикле создается неявно). Фактический такой пример будет работать правильно, если iv заранее правильно заполнить: Код vector <int> iv = {0, 1, 2, 3, 4}; int trace[5];
for (auto i : iv) { trace[i] = iv[i]; } Тогда trace: 0, 1, 2, 3, 4  Кстати, с полностью включенной оптимизацией это все выходит довольно компактно и работает шустро (судя по данным из окна disasm)! зы. Удивило, что даже статическое (или в стеке) создание "банального" vector все равно требует наличия кучи  Это как-то странно. Надо бы разобраться....
--------------------
Кругозор некоторых людей - круг с нулевым радиусом. Они называют его "точкой зрения".
|
|
|
|
|
Jul 29 2018, 16:44
|
Гуру
     
Группа: Свой
Сообщений: 3 644
Регистрация: 28-05-05
Пользователь №: 5 493

|
"несколько непривычно для восприятия цикла for," зато удобно, например скалярное умножение вектора на 2 : Код for (auto& i : iv) i *= 2; хотя в принципе можно и через разыменование итератора.. в общем как сделано так сделано "если iv заранее правильно заполнить:" мне непонятно как в микрософт попал пример с такой жуткой ошибкой " vector все равно требует наличия кучи " вектор же динамический, может увеличиваться и уменшаться на ходу. Как это статически или на стеке сделать то?
|
|
|
|
|
Jul 29 2018, 16:59
|

Профессионал
    
Группа: Свой
Сообщений: 1 215
Регистрация: 22-02-05
Пользователь №: 2 831

|
Цитата(DASM @ Jul 29 2018, 19:44)  мне непонятно как в микрософт попал пример с такой жуткой ошибкой Значит, ошибок там может быть еще больше ... Цитата " vector все равно требует наличия кучи " вектор же динамический, может увеличиваться и уменшаться на ходу. Как это статически или на стеке сделать то? Это логично при изменении размера вектора (добавляем/удаляем), но ведь не для создания же ... Это-то меня и удивляет
--------------------
Кругозор некоторых людей - круг с нулевым радиусом. Они называют его "точкой зрения".
|
|
|
|
|
Jul 29 2018, 17:15
|

Профессионал
    
Группа: Свой
Сообщений: 1 215
Регистрация: 22-02-05
Пользователь №: 2 831

|
Цитата(DASM @ Jul 29 2018, 20:08)  ничего не понял. Предлагаете делать вектор на стеке, а если понадобится изменить его - быстро перекидывать в кучу? Я про то, где хранится описательная часть вектора. Т.е. некая структура, хранящая, скажем, двусвязный список и другую служебную инфу по вектору. Короче, логика работы понятна: вектор состоит из двух "кусков": описательная часть вектора, лежит там, где создаем (стек, статика или даже куча). А сами данные - всегда в куче. По логике, получается, если вектор пустой, то и нет обращения к куче. Но даже статическое создание вектора с известным числом элементов все равно использует кучу... Разобрался )) Гы, лезем в дебри std, а это уже откровенный офф
--------------------
Кругозор некоторых людей - круг с нулевым радиусом. Они называют его "точкой зрения".
|
|
|
|
|
Aug 3 2018, 16:47
|

Профессионал
    
Группа: Свой
Сообщений: 1 215
Регистрация: 22-02-05
Пользователь №: 2 831

|
Цитата(esaulenka @ Aug 3 2018, 19:20)  Я дико извиняюсь, но почему обсуждение стандартной библиотеки языка си++ (наиболее базовых вещей из неё) - "откровенный офф" ? Эта тема вообще ни разу не про C++ и уж тем более про STL  Но тенденция "скатиться к этому" есть почему-то у каждой темы в этом разделе ... Цитата "Откровенный офф" - это пара страниц обсуждения дурацкой опечатки у майкрософта. Это не офф, это - пустой треп Цитата А STL прямо вот очень рекомендую посмотреть. Умные люди понаделали велосипедов почти на все случаи жизни. К сожалению, STL довольно толстая библиотека и, если и стоит ее использовать в конкретнтных встраиваемых приложениях, то как можно активнее. Поэтому пока что у меня лично нет возможности совать ее во все проекты без исключения. Другая причина - активное использование кучи. Причем, опасения вызывает даже не сам факт использования кучи (если "правильно ее готовить", то ничего страшного в ней нет), а то, что STL использует кучу неявно. Можно сказать, непредсказуемо. Поэтому без перегруженных new/delete уж никак не обойтись. А еще хлеще, что наверняка придется перегружать еще и локальные new/delete ("локальные", это значит - предназначенные для конкретных классов, точный термин не помню). Например, вместо фрагментируемой кучи использовать более безопасные "пулы" для конкретно взятых классов. С этой точки зрения Ваша фраза " понаделали велосипедов" может звучать уже иначе  Цитата PS для статического создания массивов есть std::array, ему куча не нужна (но при этом у него нет push()/pop()) Это все понятно ))) Книжки читать умеем ) Но речь зашла именно про vector и почему у меня он так работал. Но к счастью разобрался. Короче, проехали Цитата PPS в кишках std::vector НЕТУ двусвязного списка (и вообще списка нет). Это один сплошной массив. И да, этот массив создеётся в куче. Некая "описательная" часть этого массива все равно требует места для хранения, а точнее хранится именно там в какой области объявили этот vector. Например, для случая: std::vector <int> v = {0, 1, 2, 3, 4};sizeof(v) = 12 байт (arm compiler v6) А уже сами данные вектора хранятся в куче. Именно это момент вызвал проблемы в моем случае. Кстати, размер выделенных в куче данных может оказаться даже больше, чем было "запрошено". Таков функционал этого vector - выделяет с неким запасом. Напомню причину: у меня в текущих и старых проектах куча имеет минимально возможный размер (вроде 8 байт) и в принципе не используется, т.к. не особо-то и нужна. По-хорошему мне стоит "перегрузить" штатные malloc и free (их используют new/delete) на некие "заглушки-ловушки"...
--------------------
Кругозор некоторых людей - круг с нулевым радиусом. Они называют его "точкой зрения".
|
|
|
|
|
Aug 4 2018, 16:38
|
Гуру
     
Группа: Свой
Сообщений: 3 123
Регистрация: 7-04-07
Из: Химки
Пользователь №: 26 847

|
Цитата(Forger @ Aug 3 2018, 19:47)  Другая причина - активное использование кучи. Причем, опасения вызывает даже не сам факт использования кучи (если "правильно ее готовить", то ничего страшного в ней нет), а то, что STL использует кучу неявно. Можно сказать, непредсказуемо. Поэтому без перегруженных new/delete уж никак не обойтись. А еще хлеще, что наверняка придется перегружать еще и локальные new/delete ("локальные", это значит - предназначенные для конкретных классов, точный термин не помню). Не надо. У всех контейнеров в STL есть шаблонный параметр - аллокатор (и он практически никогда не передаётся, а используется аллокатор по умолчанию - через new/delete и кучу) Делаете свой аллокатор (с любым местом расположения объектов и алгоритмом алокации) у вуаля - всё управление кучей в ваших руках
|
|
|
|
|
Aug 4 2018, 16:44
|

Профессионал
    
Группа: Свой
Сообщений: 1 215
Регистрация: 22-02-05
Пользователь №: 2 831

|
Цитата(XVR @ Aug 4 2018, 19:38)  Не надо. У всех контейнеров в STL есть шаблонный параметр - аллокатор Тем проще )) Тем не менее, проблем с неявным обращением к куче, т.е. вызовом этого самого аллокатора, увы, все равно не избежать Фактически, при активном использовании STL, имхо, всегда нужно держать "руку на пульсе": строчить свои аллокаторы на каждый вид объектов... Повторюсь, что речь в данном случае про встраиваемые системы на обычным МК. Пока что очкую применять STL в аппаратно-критичных приложениях, а других у меня и нету ))
--------------------
Кругозор некоторых людей - круг с нулевым радиусом. Они называют его "точкой зрения".
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|