Topic: Pointers and vectors
Author: leomayleomay@gmail.com
Date: Thu, 17 May 2007 00:59:43 CST Raw View
On 5 16 , 12 44 , Philippe Gagnon <heel...@avicora.com> wrote:
> Hello,
>
> If I have a pointer to an object contained in a vector, and that
> vector is resized, would the pointer be invalidated?
>
> Thanks for your answers.
>
> ---
> [ comp.std.c++ is moderated. To submit articles, try just posting with ]
> [ your news-reader. If that fails, use mailto:std-...@ncar.ucar.edu ]
> [ --- Please see the FAQ before posting. --- ]
> [ FAQ:http://www.comeaucomputing.com/csc/faq.html ]
unless reallocation happens, all the pointer or iterators in the
vector will not invalidate.
insert and erase-remove idiom can cause pointer and iterator
invalidate as well.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: alfps@start.no ("Alf P. Steinbach")
Date: Thu, 17 May 2007 06:00:35 GMT Raw View
* Alberto Ganesh Barbati:
> Philippe Gagnon ha scritto:
>> Hello,
>>
>> If I have a pointer to an object contained in a vector, and that
>> vector is resized, would the pointer be invalidated?
>
> resize() might or might not trigger reallocation. If reallocation occurs
> then pointers to all contained objects will be invalidated. Reallocation
> occurs if and only if you call resize(n) with n > capacity().
I think you mean reserve(). Anyway, the resize() above is incorrect,
whereas reserve() would be correct. resize() may call reserve(),
reserve() doesn't call resize().
And it's necessary to consider swapping in addition to reallocation.
But in my posting in this thread where I mentioned that, I erred in the
same way as you, using too precise language. For swapping doesn't
necessarily invalidate a pointer in the sense of rendering it invalid
for all purposes. It /may/ invalidate a pointer (simplest example is
the swap-with-temporary idiom for clearing), and it /does/ invalidate
certain pointer operations such as subsequenctly comparing p > &v[0].
Sorry for stating that a swap will always invalidate pointers.
But as Alan Turing noted, the potential for at least temporarily holding
false, contradictory beliefs and communicating false statements is
necessary (although not sufficient) for intelligence... I cling to that.
[snip]
> Notice that if resize() is actually shrinking the vector then some
> objects will be erased and pointers to them will be invalidated even if
> reallocation doesn't occur.
The pointers themselves will not be invalid (e.g. can still be safely
compared with no UB), but will point to garbage. However, the standard
uses this language for references, saying they will be "invalidated",
and there the story is much the same as for pointers: the references
themselves won't be completely invalid, e.g. &r can be compared if
there's no user-defined address operator, but until perhaps the vector
is resized up again they refer to garbage.
The problem here, if there is one, is simply that the standard tries too
hard to be abstract where the opposite is called for, doing the opposite
of what we did, namely it's using too wooly language, which is probably
connected to the fact that a vector's buffer didn't become guaranteed
contiguous until C++2003 (TC1). For with a contiguous buffer and
guarantees about when the buffer isn't replaced, which are now in place,
there's no need to consult the standard at all, except perhaps to
ascertain that those guarantees are there. Simple logic suffices, which
is as it should be: it should be possible to /understand/the language.
--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: AlbertoBarbati@libero.it (Alberto Ganesh Barbati)
Date: Fri, 18 May 2007 16:11:07 GMT Raw View
Alf P. Steinbach ha scritto:
> * Alberto Ganesh Barbati:
>> Philippe Gagnon ha scritto:
>>> Hello,
>>>
>>> If I have a pointer to an object contained in a vector, and that
>>> vector is resized, would the pointer be invalidated?
>>
>> resize() might or might not trigger reallocation. If reallocation occurs
>> then pointers to all contained objects will be invalidated. Reallocation
>> occurs if and only if you call resize(n) with n > capacity().
>
> I think you mean reserve(). Anyway, the resize() above is incorrect,
> whereas reserve() would be correct. resize() may call reserve(),
> reserve() doesn't call resize().
No no, I really meant resize(). In the statement "Reallocation occurs if
and only if you call resize(n) with with n > capacity()" what I meant
was "*As an effect of a call to resize()* reallocation occurs if and
only if you call resize(n) with with n > capacity()". Of course, also
calling reserve() as well as insert() can trigger reallocation under
similar circumstances.
BTW, while resize() and insert() *may* call reserve() to perform
reallocation, they may achieve the same task *without* calling it (for
example the reallocation task might be factored out in a private
function as part of an optimization). So replacing "resize()" with
"reserve()" in the statement above doesn't make it more correct.
Regards,
Ganesh
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: Philippe Gagnon <heelios@avicora.com>
Date: Tue, 15 May 2007 22:44:51 CST Raw View
Hello,
If I have a pointer to an object contained in a vector, and that
vector is resized, would the pointer be invalidated?
Thanks for your answers.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: alfps@start.no ("Alf P. Steinbach")
Date: Wed, 16 May 2007 04:59:40 GMT Raw View
* Philippe Gagnon:
>
> If I have a pointer to an object contained in a vector, and that
> vector is resized, would the pointer be invalidated?
Depends (a more precise question would allow a more precise answer).
The vector's buffer can be replaced in two ways: reallocation and swap.
A reallocation happens if and only if a capacity greater than the
current capacity() is required for some operation.
If and only if the buffer is replaced, the pointer will be invalid as a
pointer.
However, assuming no buffer replacement, if p >= &v[0]+v.size() after
your operation(s), then p effectively points to raw storage: the pointer
itself is still valid, e.g. can be compared, but points to garbage.
--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: AlbertoBarbati@libero.it (Alberto Ganesh Barbati)
Date: Wed, 16 May 2007 17:31:22 GMT Raw View
Philippe Gagnon ha scritto:
> Hello,
>
> If I have a pointer to an object contained in a vector, and that
> vector is resized, would the pointer be invalidated?
>
resize() might or might not trigger reallocation. If reallocation occurs
then pointers to all contained objects will be invalidated. Reallocation
occurs if and only if you call resize(n) with n > capacity(). You can
set the value of capacity() by calling reserve(). You should call
reserve() *before* inserting the elements, because reserve() may (and
probably will) trigger reallocation. The idea is to call reserve() when
the vector is empty (thus when reallocation doesn't bother you) and then
do whatever you want with the vector by just being careful not to exceed
capacity().
Notice that if resize() is actually shrinking the vector then some
objects will be erased and pointers to them will be invalidated even if
reallocation doesn't occur.
HTH,
Ganesh
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]