Выход итератора за пределы vector::end()
От: Чили Россия  
Дата: 26.11.09 13:04
Оценка: +1 :)
Банальная конструкция:
std::vector<int> vec;
vec.push_back(10);     // вектор из 1 элемента
for (std::vector<int>::iterator it = vec.begin(); it != vec.end(); it = it + 2)
{
    // что-то делаем с it (например в него пишем!)
}

В данном примере условие it != vec.end() никогда не выполняется и мы бесконечно пишем за пределами списка, нарушая кем-то занятую память.
Вопрос:
Можно ли как-то отследить выход за пределы списка?
Re: Выход итератора за пределы vector::end()
От: Alex Dav Россия  
Дата: 26.11.09 13:08
Оценка: :)
Здравствуйте, Чили, Вы писали:

Ч>Банальная конструкция:

Ч>
Ч>std::vector<int> vec;
Ч>vec.push_back(10);     // вектор из 1 элемента
Ч>for (std::vector<int>::iterator it = vec.begin(); it != vec.end(); it = it + 2)
Ч>{
Ч>    // что-то делаем с it (например в него пишем!)
Ч>}
Ч>

Ч>В данном примере условие it != vec.end() никогда не выполняется и мы бесконечно пишем за пределами списка, нарушая кем-то занятую память.
Ч>Вопрос:
Ч>Можно ли как-то отследить выход за пределы списка?

for (std::vector<int>::iterator it = vec.begin(); it != vec.end(),it+1 != vec.end(); it = it + 2)
Re: Выход итератора за пределы vector::end()
От: rg45 СССР  
Дата: 26.11.09 13:18
Оценка:
Здравствуйте, Чили, Вы писали:

Ч>Банальная конструкция:

Ч>
Ч>std::vector<int> vec;
Ч>vec.push_back(10);     // вектор из 1 элемента
Ч>for (std::vector<int>::iterator it = vec.begin(); it != vec.end(); it = it + 2)
Ч>{
Ч>    // что-то делаем с it (например в него пишем!)
Ч>}
Ч>

Ч>В данном примере условие it != vec.end() никогда не выполняется и мы бесконечно пишем за пределами списка, нарушая кем-то занятую память.
Ч>Вопрос:
Ч>Можно ли как-то отследить выход за пределы списка?

Ну, например так (не компилировал):
template<typename IteratorT>
void safe_advance(IteratorT& i, int increment, IteratorT end)
{
  inrement = std::min(increment, std::distance(i, end));
  std::advance(i, increment);
}

std::vector<int> vec;
vec.push_back(10);     // вектор из 1 элемента
for (std::vector<int>::iterator it = vec.begin(); it != vec.end(); safe_advance(it, 2, vec.end()))
{
    // что-то делаем с it (например в него пишем!)
}
--
Не можешь достичь желаемого — пожелай достигнутого.
Re[2]: Выход итератора за пределы vector::end()
От: abrec Россия  
Дата: 26.11.09 13:30
Оценка: -1
Здравствуйте, Alex Dav, Вы писали:

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


AD>for (std::vector<int>::iterator it = vec.begin(); it != vec.end(),it+1 != vec.end(); it = it + 2)


Для std::list такое не пройдет

Ч>Можно ли как-то отследить выход за пределы списка?


Для конкретно вектора
for (std::size_t it = 0; it < vec.size(); it = it + 2)
{
    // что-то делаем с vec[it] (например в него пишем!)
}


Для листа
for (std::size_t it = 0; it < vec.size(); it = it + 2)
{
    std::list<int>::iterator iter;
    std::advance( iter = vec.begin(), it );
    // что-то делаем с iter (например в него пишем!)
}
Re[2]: Выход итератора за пределы vector::end()
От: Caracrist https://1pwd.org/
Дата: 26.11.09 13:33
Оценка:
Здравствуйте, rg45, Вы писали:


R>template<typename IteratorT>
R>void safe_advance(IteratorT& i, int increment, IteratorT end)
R>{
R>  inrement = std::min(increment, std::distance(i, end));
R>  std::advance(i, increment);
R>}


std::distance --- std::list ?
~~~~~
~lol~~
~~~ Single Password Solution
Re: Выход итератора за пределы vector::end()
От: _DAle_ Беларусь  
Дата: 26.11.09 13:35
Оценка: 1 (1) +1
Здравствуйте, Чили, Вы писали:

Ч>Банальная конструкция:

Ч>
Ч>std::vector<int> vec;
Ч>vec.push_back(10);     // вектор из 1 элемента
Ч>for (std::vector<int>::iterator it = vec.begin(); it != vec.end(); it = it + 2)
Ч>{
Ч>    // что-то делаем с it (например в него пишем!)
Ч>}
Ч>

Ч>В данном примере условие it != vec.end() никогда не выполняется и мы бесконечно пишем за пределами списка, нарушая кем-то занятую память.
Ч>Вопрос:
Ч>Можно ли как-то отследить выход за пределы списка?

Я с векторами обычно все-таки пишу так..
std::vector<int> vec;
vec.push_back(10);     // вектор из 1 элемента
for (size_t i = 0; i < vec.size(); i += 2)
{
   
}
Re[3]: Выход итератора за пределы vector::end()
От: rg45 СССР  
Дата: 26.11.09 13:38
Оценка:
Здравствуйте, Caracrist, Вы писали:

C>std::distance --- std::list ?


Для списка тоскливо, конечно, по алгоритмической сложности — O(N). С другой стороны, нужно учитывать специфику задачи. Если больших величин инкремента в рамках конкретной задачи не возникает, то, возможно такая цена за надежность окажется вполне приемлемой.
--
Не можешь достичь желаемого — пожелай достигнутого.
Re[2]: Выход итератора за пределы vector::end()
От: Caracrist https://1pwd.org/
Дата: 26.11.09 13:50
Оценка: 1 (1)
Здравствуйте, rg45, Вы писали:


template<typename IteratorT>
void safe_advance(IteratorT& i, int increment, IteratorT end)
{
increment = min(increment, end — i);
std::advance(i, increment);
}

template<typename IteratorT>
void safe_advance_list(IteratorT& i, int increment, IteratorT end)
{
while (increment-->0)
{
if (i != end) i++;
else break;
}
}

std::vector<int> vec;
vec.push_back(10);
for (std::vector<int>::iterator it = vec.begin(); it != vec.end(); safe_advance(it, 2, vec.end()))
{

}

std::list<int> lis;
lis.push_back(10);
for (std::list<int>::iterator it = lis.begin(); it != lis.end(); safe_advance_list(it, 2, lis.end()))
{

}
[/ccode]
~~~~~
~lol~~
~~~ Single Password Solution
Re: недостатки stl
От: Erop Россия  
Дата: 26.11.09 14:11
Оценка: :)
Здравствуйте, Чили, Вы писали:

Ч>Можно ли как-то отследить выход за пределы списка?


Ох и баянистый у вас баян
Автор: gid_vvp
Дата: 23.08.06
, хозяин...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[3]: Выход итератора за пределы vector::end()
От: Alex Dav Россия  
Дата: 26.11.09 14:36
Оценка:
Здравствуйте, abrec, Вы писали:

A>Здравствуйте, Alex Dav, Вы писали:


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


AD>>for (std::vector<int>::iterator it = vec.begin(); it != vec.end(),it+1 != vec.end(); it = it + 2)


A>Для std::list такое не пройдет


почему?
Re[4]: Выход итератора за пределы vector::end()
От: abrec Россия  
Дата: 26.11.09 15:07
Оценка:
Здравствуйте, Alex Dav, Вы писали:

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


A>>Здравствуйте, Alex Dav, Вы писали:


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


AD>>>for (std::vector<int>::iterator it = vec.begin(); it != vec.end(),it+1 != vec.end(); it = it + 2)


A>>Для std::list такое не пройдет


AD>почему?

it+1 != vec.end()
така арифметика для итераторов произвольного доступа
Re[3]: Выход итератора за пределы vector::end()
От: посетитель /life/  
Дата: 26.11.09 16:38
Оценка:
Здравствуйте, abrec, Вы писали:

A>Здравствуйте, Alex Dav, Вы писали:


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


AD>>for (std::vector<int>::iterator it = vec.begin(); it != vec.end(),it+1 != vec.end(); it = it + 2)


A>Для std::list такое не пройдет


А причем тут std::list? Автор говорил только про std::vector. Для std::list вопрос не имеет смысла, потому что выражение из исходного примера "it = it + 2" не будет работать.


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

C>std::distance --- std::list ?


Тот же вопрос. Зачем пытаться обобщить на std::list, если никто этого не просит?
Re[5]: Выход итератора за пределы vector::end()
От: Alex Dav Россия  
Дата: 26.11.09 17:06
Оценка: +2
Здравствуйте, abrec, Вы писали:

A>>>Для std::list такое не пройдет


AD>>почему?

A>it+1 != vec.end()
A>така арифметика для итераторов произвольного доступа

а такая it = it + 2?
Re[2]: Выход итератора за пределы vector::end()
От: Чили Россия  
Дата: 27.11.09 06:32
Оценка:
Здравствуйте, Alex Dav, Вы писали:

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


AD>for (std::vector<int>::iterator it = vec.begin(); it != vec.end(),it+1 != vec.end(); it = it + 2)


Не стоит привязываться к it = it + 2
допустим
for (std::vector<int>::iterator it = vec.begin(); it != vec.end(),it+1 != vec.end(); )
{
     if (условие)
        it = it + 2;
     else
        it = it + 3;
     else
        it = it + 4;
     else
        ...

Вполне рабочая конструкция!!!
Re[3]: Выход итератора за пределы vector::end()
От: Alex Dav Россия  
Дата: 27.11.09 06:39
Оценка:
Здравствуйте, Чили, Вы писали:

Ч>Не стоит привязываться к it = it + 2

Ч>допустим
Ч>
Ч>for (std::vector<int>::iterator it = vec.begin(); it != vec.end(),it+1 != vec.end(); )
Ч>{
Ч>     if (условие)
Ч>        it = it + 2;
Ч>     else
Ч>        it = it + 3;
Ч>     else
Ч>        it = it + 4;
Ч>     else
Ч>        ...
Ч>

Ч>Вполне рабочая конструкция!!!
не спорю что рабочая — в таком случае я бы написал it = it + n;
а для it = it + 2 — мой вариант вполне рабочий
в любом случае — спасибо вам за вопрос — было позновательно почитать ответы
Re: Выход итератора за пределы vector::end()
От: Чили Россия  
Дата: 27.11.09 06:43
Оценка:
Здравствуйте, Чили, Вы писали:

Ч>Банальная конструкция:

Ч>
Ч>std::vector<int> vec;
Ч>vec.push_back(10);     // вектор из 1 элемента
Ч>for (std::vector<int>::iterator it = vec.begin(); it != vec.end(); it = it + 2)
Ч>{
Ч>    // что-то делаем с it (например в него пишем!)
Ч>}
Ч>

Ч>В данном примере условие it != vec.end() никогда не выполняется и мы бесконечно пишем за пределами списка, нарушая кем-то занятую память.
Ч>Вопрос:
Ч>Можно ли как-то отследить выход за пределы списка?
Уважаемые коллеги !!!
Вы предлагаете решение частного цикла:
Ч>
Ч>for (std::vector<int>::iterator it = vec.begin(); it != vec.end(); it = it + 2)
Ч>{
Ч>    // что-то делаем с it (например в него пишем!)
Ч>}
Ч>

а ведь могут быть другие ситуации, напр.:
Ч>
Ч>std::vector<int> vec(5);
Ч>std::vector<int>::iterator it = vec.begin()+10; // выход за пределы списка !!!
Ч>

Хочется как-то обезопасить себя от подобных моментов.
Re[2]: Выход итератора за пределы vector::end()
От: Vain Россия google.ru
Дата: 27.11.09 08:13
Оценка: +1
Здравствуйте, Чили, Вы писали:

Ч>>
Ч>>std::vector<int> vec(5);
Ч>>std::vector<int>::iterator it = vec.begin()+10; // выход за пределы списка !!!
Ч>>

Ч>Хочется как-то обезопасить себя от подобных моментов.
Юзать счётчик религия не позволяет?
std::vector<int> vec;
vec.push_back(10);     // вектор из 1 элемента
std::vector<int>::iterator it = vec.begin();
std::vector<int>::iterator itNext = it;
for (unsigned int i = 0; i < vec.size(); it = itNext, i += 2)
{
    if(i+2 < vec.size())
    {
        itNext = itNext+2;
    }
    // что-то делаем с it (например в него пишем!)
}

std::vector<int> vec(5);
std::vector<int>::iterator it = 10 < vec.size() ? vec.begin()+10 : vec.end();
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]
Re: Выход итератора за пределы vector::end()
От: se_sss  
Дата: 27.11.09 11:37
Оценка:
Как-то так:
std::vector<int> vec;
vec.push_back(10);     // вектор из 1 элемента
for (std::vector<int>::iterator it = vec.begin(); it != vec.end(); )
{
    // что-то делаем с it (например в него пишем!)

 if(it + 1 != vec.end();)
   it = it + 2;
 else break;
}



Пользоваться указателем на элемент через 1 от последнего нехорошо даже в чисом C массиве.
Re[2]: Выход итератора за пределы vector::end()
От: Caracrist https://1pwd.org/
Дата: 27.11.09 12:49
Оценка:
Здравствуйте, Чили, Вы писали:

Ч>а ведь могут быть другие ситуации, напр.:

Ч>>
Ч>>std::vector<int> vec(5);
Ч>>std::vector<int>::iterator it = vec.begin()+10; // выход за пределы списка !!!
Ч>>

Ч>Хочется как-то обезопасить себя от подобных моментов.


смотрите в соседней ветке
Автор: Caracrist
Дата: 26.11.09
общее решение...
safe_advance
и
safe_advance_list
~~~~~
~lol~~
~~~ Single Password Solution
Re[3]: Выход итератора за пределы vector::end()
От: IROV..  
Дата: 30.11.09 21:05
Оценка: 7 (2)
template<typename IteratorT, typename IteratorC>
struct safe_advance_t;

template<typename IteratorT>
struct safe_advance_t<IteratorT, std::bidirectional_iterator_tag>
{
    static void apply(IteratorT& i, int increment, IteratorT end)
    {
        while( (++i != end) && (--increment) );
    }
};

template<typename IteratorT>
struct safe_advance_t<IteratorT, std::random_access_iterator_tag>
{
    static void apply(IteratorT& i, int increment, IteratorT end)
    {
        increment = std::min( increment, std::distance( i, end ) );
        std::advance(i, increment);
    }
};

template<typename IteratorT>
void safe_advance(IteratorT& i, int increment, IteratorT end )
{
    safe_advance_t<IteratorT, typename IteratorT::iterator_category>::apply( i, increment, end );
}

void main()
{
    std::vector<int> vec;
    vec.push_back(10);     // вектор из 1 элемента
    for (std::vector<int>::iterator it = vec.begin(); it != vec.end(); safe_advance(it, 2, vec.end()))
    {

    }

    std::list<int> lis;
    lis.push_back(10); 
    for (std::list<int>::iterator it = lis.begin(); it != lis.end(); safe_advance(it, 2, lis.end()))
    {

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