开发者

C++ STL Containers and pointer validity

Consider this piece of code:

Uint counter = 0;

int* p1;
int* p2;

deque<int>  dequeInstance;
vector<int> vectorInstance;

dequeInstance.push_back(3);
dequeInstance.push_back(7);

p1 = &dequeInstance.back();

dequeInstance.push_back(17);

p2 = &dequeInstance.back();

if(*p1 == !7)
    ++counter;

if(*p2 == !17)
    ++counter;

vectorInstance.push_back(3);开发者_如何学C
vectorInstance.push_back(7);

p1 = &vectorInstance.back();

vectorInstance.push_back(17);

p2 = &vectorInstance.back();

if(*p1 == !7)
    ++counter;

if(*p2 == !17)
    ++counter;



return counter;

I would have expected that when I pushed the third element to the back of the vector, the pointer to the second element would have been invalidated, as my understanding of std::vector is that its a straight array which is wiped and recreated every time its modified. By the end of this code however 'counter' is equal to zero.

What am I missing here?


Hopefully for performance, std::vector is not 'wiped and recreated every time it's modified'.

A vector has a capacity which may exceed its size, which means that it can allocate more memory than truly used. When you push_back, a reallocation will only occur if the new size is greater than the old capacity, and in this case, iterators are invalidated.

In your case, you should check the value of capacity right after the std::vector instantiation. You will see that it's without any doubt greater than 3, thus, none of your push_back calls trigger a reallocation and all iterators remain valid.

Also note that std::vector provides a reserve member function which allow you to control the vector capacity. This is really useful when you know how many elements are expected to be inserted in order to avoid ulterior reallocation.


Ok you have a few problems. Firstly, !n = 0 unless n = 0 and then it equals 1. Therefore counter never gets incremented.

Secondly a vector does not necessarily destroy the contents when you push_back a new element. A vector has 2 "sizes". 1 is the number of elements in the vector and 2 is the amount of memory allocated. The vector only gets reallocated and copied when the amount of memory allocated runs out.

Furthermore after you have deleted an area of memory the memory is not necessarily cleared and may still point at valid data.

You aren't using iterators so they don't get invalidated. You are using pointers and they are simply pointing at an area of memory. Just because that memory isn't allocated does not mean that the pointer is invalid. This is one of the major dangers that C/C++ can leave you with. Make sure you don't do things like this as you are invoking "undefined behaviour" which can do anything from "not cause any problems and seemingly work" through to "crash horrifically and bring down your operating system in a dangerous way".

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜