Forger 19 27 июля, 2018 Опубликовано 27 июля, 2018 · Жалоба 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 или что-то подобное. Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
DASM 0 27 июля, 2018 Опубликовано 27 июля, 2018 · Жалоба Это int. Дома посмотрю, почему у Вас сомнения Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
DASM 0 29 июля, 2018 Опубликовано 29 июля, 2018 · Жалоба Проверил, это точно int , собственно и сомнений не было. Итераторы конечно используются для такого for, но тип i - это int vector <int> iv (5, 1); for (auto i : iv) { int tmp; decltype (i) intger = 0; tmp = intger; intger = tmp; } Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Forger 19 29 июля, 2018 Опубликовано 29 июля, 2018 · Жалоба Проверил, это точно int , собственно и сомнений не было. Итераторы конечно используются для такого for, но тип i - это int Попробуйте это i присваивать внутри цикла например в какой нить примитивный массив из int, но для индексации внутри массива НЕ используйте саму i. Что будет в массиве при выходе из цикла? Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
DASM 0 29 июля, 2018 Опубликовано 29 июля, 2018 · Жалоба Попробуйте это i присваивать внутри цикла например в какой нить примитивный массив из int, но для индексации внутри массива НЕ используйте саму i. Что будет в массиве при выходе из цикла? vector <int> iv (5, 1); int trace[5]; int ix = 0; for (auto i : iv) { trace[ix++] = i; } trace стал 1,1,1,1,1 что абсолютно верно Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Forger 19 29 июля, 2018 Опубликовано 29 июля, 2018 · Жалоба Заглумил я тут всех :) Короче, увеличил кучу, все стало работать правильно! Дело было в том, что куча у меня не используется и на нее выделяется от силы 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 все равно требует наличия кучи :( Это как-то странно. Надо бы разобраться.... Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
DASM 0 29 июля, 2018 Опубликовано 29 июля, 2018 · Жалоба "несколько непривычно для восприятия цикла for," зато удобно, например скалярное умножение вектора на 2 : for (auto& i : iv) i *= 2; хотя в принципе можно и через разыменование итератора.. в общем как сделано так сделано "если iv заранее правильно заполнить:" мне непонятно как в микрософт попал пример с такой жуткой ошибкой " vector все равно требует наличия кучи " вектор же динамический, может увеличиваться и уменшаться на ходу. Как это статически или на стеке сделать то? Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Forger 19 29 июля, 2018 Опубликовано 29 июля, 2018 · Жалоба мне непонятно как в микрософт попал пример с такой жуткой ошибкойЗначит, ошибок там может быть еще больше ... " vector все равно требует наличия кучи " вектор же динамический, может увеличиваться и уменшаться на ходу. Как это статически или на стеке сделать то? Это логично при изменении размера вектора (добавляем/удаляем), но ведь не для создания же ... Это-то меня и удивляет :wacko: Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
DASM 0 29 июля, 2018 Опубликовано 29 июля, 2018 · Жалоба ничего не понял. Предлагаете делать вектор на стеке, а если понадобится изменить его - быстро перекидывать в кучу? Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Forger 19 29 июля, 2018 Опубликовано 29 июля, 2018 · Жалоба ничего не понял. Предлагаете делать вектор на стеке, а если понадобится изменить его - быстро перекидывать в кучу? Я про то, где хранится описательная часть вектора. Т.е. некая структура, хранящая, скажем, двусвязный список и другую служебную инфу по вектору. Короче, логика работы понятна: вектор состоит из двух "кусков": описательная часть вектора, лежит там, где создаем (стек, статика или даже куча). А сами данные - всегда в куче. По логике, получается, если вектор пустой, то и нет обращения к куче. Но даже статическое создание вектора с известным числом элементов все равно использует кучу... Разобрался )) Гы, лезем в дебри std, а это уже откровенный офф :) Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
esaulenka 5 3 августа, 2018 Опубликовано 3 августа, 2018 · Жалоба Я дико извиняюсь, но почему обсуждение стандартной библиотеки языка си++ (наиболее базовых вещей из неё) - "откровенный офф" ? "Откровенный офф" - это пара страниц обсуждения дурацкой опечатки у майкрософта. А STL прямо вот очень рекомендую посмотреть. Умные люди понаделали велосипедов почти на все случаи жизни. PS для статического создания массивов есть std::array, ему куча не нужна (но при этом у него нет push()/pop()) PPS в кишках std::vector НЕТУ двусвязного списка (и вообще списка нет). Это один сплошной массив. И да, этот массив создеётся в куче. Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Forger 19 3 августа, 2018 Опубликовано 3 августа, 2018 · Жалоба Я дико извиняюсь, но почему обсуждение стандартной библиотеки языка си++ (наиболее базовых вещей из неё) - "откровенный офф" ? Эта тема вообще ни разу не про C++ и уж тем более про STL ;) Но тенденция "скатиться к этому" есть почему-то у каждой темы в этом разделе ... "Откровенный офф" - это пара страниц обсуждения дурацкой опечатки у майкрософта. Это не офф, это - пустой треп B) А STL прямо вот очень рекомендую посмотреть. Умные люди понаделали велосипедов почти на все случаи жизни. К сожалению, STL довольно толстая библиотека и, если и стоит ее использовать в конкретнтных встраиваемых приложениях, то как можно активнее. Поэтому пока что у меня лично нет возможности совать ее во все проекты без исключения. Другая причина - активное использование кучи. Причем, опасения вызывает даже не сам факт использования кучи (если "правильно ее готовить", то ничего страшного в ней нет), а то, что STL использует кучу неявно. Можно сказать, непредсказуемо. Поэтому без перегруженных new/delete уж никак не обойтись. А еще хлеще, что наверняка придется перегружать еще и локальные new/delete ("локальные", это значит - предназначенные для конкретных классов, точный термин не помню). Например, вместо фрагментируемой кучи использовать более безопасные "пулы" для конкретно взятых классов. С этой точки зрения Ваша фраза "понаделали велосипедов" может звучать уже иначе ;) PS для статического создания массивов есть std::array, ему куча не нужна (но при этом у него нет push()/pop()) Это все понятно ))) Книжки читать умеем ) Но речь зашла именно про vector и почему у меня он так работал. Но к счастью разобрался. Короче, проехали :laughing: 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) на некие "заглушки-ловушки"... Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
xvr 12 4 августа, 2018 Опубликовано 4 августа, 2018 · Жалоба Другая причина - активное использование кучи. Причем, опасения вызывает даже не сам факт использования кучи (если "правильно ее готовить", то ничего страшного в ней нет), а то, что STL использует кучу неявно. Можно сказать, непредсказуемо. Поэтому без перегруженных new/delete уж никак не обойтись. А еще хлеще, что наверняка придется перегружать еще и локальные new/delete ("локальные", это значит - предназначенные для конкретных классов, точный термин не помню). Не надо. У всех контейнеров в STL есть шаблонный параметр - аллокатор (и он практически никогда не передаётся, а используется аллокатор по умолчанию - через new/delete и кучу) Делаете свой аллокатор (с любым местом расположения объектов и алгоритмом алокации) у вуаля - всё управление кучей в ваших руках :) Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Forger 19 4 августа, 2018 Опубликовано 4 августа, 2018 · Жалоба Не надо. У всех контейнеров в STL есть шаблонный параметр - аллокатор Тем проще )) Тем не менее, проблем с неявным обращением к куче, т.е. вызовом этого самого аллокатора, увы, все равно не избежать Фактически, при активном использовании STL, имхо, всегда нужно держать "руку на пульсе": строчить свои аллокаторы на каждый вид объектов... Повторюсь, что речь в данном случае про встраиваемые системы на обычным МК. Пока что очкую применять STL в аппаратно-критичных приложениях, а других у меня и нету )) Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Kabdim 0 5 августа, 2018 Опубликовано 5 августа, 2018 · Жалоба Не стоит забывать что stl который с компилятором не прибит гвоздями. В геймдеве схожие с эмбедедом проблемы и написаны адаптированные под такие проблемы библиотеки. EASTL например, который выглядит намного разумней того что предлагает стандарт и производители компиляторов. Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться