LINUX.ORG.RU

Указатели на элементы перечисляющих контейнеров

 ,


1

2

Обнаружил тут, что если взять указатель на элемент std::vector, а потом сделать скажем push_back, то указатель начинает указывать на чушь.

Когда я с этим столкнулся, то понял из-за чего (скорее всего realloc какой-нибудь), вопрос не в этом. Вопрос в том: как ведут себя другие такие контейнеры (мапы, списки, очереди)? Платформозависимо ли это, или оговоренно в стандарте? Если второе, то прошу ткнуть носом. Спасибо.

★★★★★

В стандарте оговорено не про указатели, а про итераторы. Для мап и списков итератор остаётся валидным, если только не удалять элемент по этому итератору. Про deque не помню точно, скорее всего, в общем случае итераторы инвалидируются, хотя для вставки/удаления в начало/конец инвалидировать незачем.

const86 ★★★★★
()

Контейнер вправе копировать объект, когда ему это надо. Поэтому указатель вполне может стать невалидным.

DELIRIUM ☆☆☆☆☆
()

В документации про итераторы это было где-то. Я точно это где-то видел на cplusplus.com. В смысле инфу, после каких действий с итератором или контейнером, первый становится невалидным.

nanoolinux ★★★★
()

Qt и java-style pointers, а в stl при изменении контейнера любой указатель/итератор может стать невалидным, т.к. он же не следит за тем, как объект перераспределяет память. Так же в Qt есть умный указатель, становящийся null при разрушении объекта откуда-то из другого места, в stl такого опять же не предусмотрено, т.к. трудно сделать универсально.

quiet_readonly ★★★★
()
Ответ на: комментарий от quiet_readonly

в stl при изменении контейнера любой указатель/итератор может стать невалидным

чушь

jtootf ★★★★★
()

От реализации контейнера зависит. Списки и (возможно) мапы так себя не ведут, посколько не realloc-ом изменяются. Очереди и векторы, AFAIK, на массивах базируются, поэтому инвалидируются, да.

schizoid ★★★
()
Ответ на: комментарий от quiet_readonly

а в stl при изменении контейнера любой указатель/итератор может стать невалидным, т.к. он же не следит за тем, как объект перераспределяет память.

4.2

все случаи когда итераторы становятся невалидными оговорены

в stl такого опять же не предусмотрено, т.к. трудно сделать универсально.

В C++2011 уже есть.

Reset ★★★★★
()
Ответ на: комментарий от quiet_readonly

в stl такого опять же не предусмотрено

уже сказали про С++11, и не надо называть стандартную библиотеку С++ STL, STL это лишь ее часть

wota ★★
()

а что мешает не кешировать этот указатель? просто везде фигачить &cont.at(i), или

 &cont [i]
для совсем дерзких.

nikitos ★★★
()

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

m0rph ★★★★★
()
Ответ на: комментарий от JackyTreehorn

А желание после изменения содержимого контейнера иметь тот же адрес внутренних структур это как, эталон дизайна?

nikitos ★★★
()
Ответ на: комментарий от nikitos

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

Dudraug ★★★★★
() автор топика
Ответ на: комментарий от Dudraug

Если пользуешься готовым - будь добр, читай документацию. В данном случае - на реализацию STL. Если она не даёт желаемого (адрес изменился) - либо нелюбимый эстетами говнокод, либо другая (своя?) реализация STL.

nikitos ★★★
()

если очень надо, сделай movaable & noncopyable класс и обучи его уведомлять стороннюю переменную о его положении.

ckotinko ☆☆☆
()
Ответ на: комментарий от nikitos

Вообще-то я и попросил ткнуть меня носом. Меня выше ткнули и «В любом контейнере у тебя нет гарантии, что указатель на элемент после некоторых операций будет оставаться валидным.» как оказалось 4.2

Dudraug ★★★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.