Перейти к содержанию
    

А почему так инициализация

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 или что-то подобное.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Это int. Дома посмотрю, почему у Вас сомнения

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Проверил, это точно int , собственно и сомнений не было. Итераторы конечно используются для такого for, но тип i - это int

    vector <int> iv (5, 1);
    for (auto i : iv)
    {
        int tmp;
        decltype (i) intger = 0;
        tmp = intger;
        intger = tmp;        
    }

post-5493-1532866505_thumb.png

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Проверил, это точно int , собственно и сомнений не было. Итераторы конечно используются для такого for, но тип i - это int

Попробуйте это i присваивать внутри цикла например в какой нить примитивный массив из int, но для индексации внутри массива НЕ используйте саму i.

Что будет в массиве при выходе из цикла?

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Попробуйте это 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 что абсолютно верно

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Заглумил я тут всех :)

Короче, увеличил кучу, все стало работать правильно! Дело было в том, что куча у меня не используется и на нее выделяется от силы 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 все равно требует наличия кучи :(

Это как-то странно. Надо бы разобраться....

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

"несколько непривычно для восприятия цикла for," зато удобно, например скалярное умножение вектора на 2 :

for (auto& i : iv)
  i *= 2;

хотя в принципе можно и через разыменование итератора.. в общем как сделано так сделано

"если iv заранее правильно заполнить:" мне непонятно как в микрософт попал пример с такой жуткой ошибкой

" vector все равно требует наличия кучи " вектор же динамический, может увеличиваться и уменшаться на ходу. Как это статически или на стеке сделать то?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

мне непонятно как в микрософт попал пример с такой жуткой ошибкой
Значит, ошибок там может быть еще больше ...

 

" vector все равно требует наличия кучи " вектор же динамический, может увеличиваться и уменшаться на ходу. Как это статически или на стеке сделать то?

Это логично при изменении размера вектора (добавляем/удаляем), но ведь не для создания же ... Это-то меня и удивляет :wacko:

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

Я про то, где хранится описательная часть вектора. Т.е. некая структура, хранящая, скажем, двусвязный список и другую служебную инфу по вектору.

Короче, логика работы понятна: вектор состоит из двух "кусков": описательная часть вектора, лежит там, где создаем (стек, статика или даже куча).

А сами данные - всегда в куче.

По логике, получается, если вектор пустой, то и нет обращения к куче.

Но даже статическое создание вектора с известным числом элементов все равно использует кучу... Разобрался ))

 

Гы, лезем в дебри std, а это уже откровенный офф :)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я дико извиняюсь, но почему обсуждение стандартной библиотеки языка си++ (наиболее базовых вещей из неё) - "откровенный офф" ?

 

"Откровенный офф" - это пара страниц обсуждения дурацкой опечатки у майкрософта.

 

А STL прямо вот очень рекомендую посмотреть. Умные люди понаделали велосипедов почти на все случаи жизни.

 

PS для статического создания массивов есть std::array, ему куча не нужна (но при этом у него нет push()/pop())

PPS в кишках std::vector НЕТУ двусвязного списка (и вообще списка нет). Это один сплошной массив. И да, этот массив создеётся в куче.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я дико извиняюсь, но почему обсуждение стандартной библиотеки языка си++ (наиболее базовых вещей из неё) - "откровенный офф" ?

Эта тема вообще ни разу не про 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) на некие "заглушки-ловушки"...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Другая причина - активное использование кучи.

Причем, опасения вызывает даже не сам факт использования кучи (если "правильно ее готовить", то ничего страшного в ней нет),

а то, что STL использует кучу неявно. Можно сказать, непредсказуемо. Поэтому без перегруженных new/delete уж никак не обойтись.

А еще хлеще, что наверняка придется перегружать еще и локальные new/delete ("локальные", это значит - предназначенные для конкретных классов, точный термин не помню).

Не надо. У всех контейнеров в STL есть шаблонный параметр - аллокатор (и он практически никогда не передаётся, а используется аллокатор по умолчанию - через new/delete и кучу)

Делаете свой аллокатор (с любым местом расположения объектов и алгоритмом алокации) у вуаля - всё управление кучей в ваших руках :)

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Не надо. У всех контейнеров в STL есть шаблонный параметр - аллокатор

Тем проще ))

Тем не менее, проблем с неявным обращением к куче, т.е. вызовом этого самого аллокатора, увы, все равно не избежать

Фактически, при активном использовании STL, имхо, всегда нужно держать "руку на пульсе": строчить свои аллокаторы на каждый вид объектов...

Повторюсь, что речь в данном случае про встраиваемые системы на обычным МК.

Пока что очкую применять STL в аппаратно-критичных приложениях, а других у меня и нету ))

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Не стоит забывать что stl который с компилятором не прибит гвоздями. В геймдеве схожие с эмбедедом проблемы и написаны адаптированные под такие проблемы библиотеки. EASTL например, который выглядит намного разумней того что предлагает стандарт и производители компиляторов.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Гость
Эта тема закрыта для публикации ответов.
×
×
  • Создать...