Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What happen to pointers when vectors need more memory and realocate memory?

When vector needs more memory it will reallocate memory somewhere, I don't know where yet! and then pointers become invalid, is there any good explanation on this?

I mean where they go, what happen to my containers? ( not linked list ones )

like image 748
Synxmax Avatar asked Nov 24 '11 18:11

Synxmax


People also ask

What happens when vector is full?

The memory allocated won't change but the last element will have its destructor called and the end pointer moves one position down.

Do vectors dynamically allocate memory?

Arrays have to be deallocated explicitly if defined dynamically whereas vectors are automatically de-allocated from heap memory. Size of array cannot be determined if dynamically allocated whereas Size of the vector can be determined in O(1) time.

Are vectors stored contiguously in memory?

Vectors are assigned memory in blocks of contiguous locations. When the memory allocated for the vector falls short of storing new elements, a new memory block is allocated to vector and all elements are copied from the old location to the new location. This reallocation of elements helps vectors to grow when required.

Does vector Reserve allocate memory?

vector::reserve does allocate memory, so your question about reserving memory without allocating is incorrect. The point is that reserving memory can be done without changing the vectors size. Basically a vector has two sizes, it's size and it's capacity.


2 Answers

Short answer: Everything will be fine. Don't worry about this and get back to work.

Medium answer: Adding elements to or removing them from a vector invalidates all iterators and references/pointers (possibly with the exception of removing from the back). Simple as that. Don't refer to any old iterators and obtain new ones after such an operation. Example:

std::vector<int> v = get_vector();

int & a = v[6];
int * b = &v[7];
std::vector<int>::iterator c = v.begin();
std::advance(it, 8);

v.resize(100);

Now a, b and c are all invalid: You cannot use a, and you cannot dereference b or c.

Long answer: The vector keeps track of dynamic memory. When the memory is exhausted, it allocates a new, larger chunk elsewhere and copies (or moves) all the old elements over (and then frees up the old memory, destroying the old objects). Memory allocation and deallocation is done by the allocator (typically std::allocator<T>), which in turn usually invokes ::operator new() to fetch memory, which in turn usually calls malloc(). Details may vary and depend on your platform. In any event, any previously held references, pointers or iterators are no longer valid (presumably because they refer to the now-freed memory, though it's not specified in the standard why they're invalid).

like image 136
Kerrek SB Avatar answered Nov 15 '22 16:11

Kerrek SB


When you add or remove items from a vector, all iterators (and pointers) to items within it are invalidated. If you need to store a pointer to an item in a vector, then make the vector const, or use a different container.

It shouldn't matter to you where the vector stores things. You don't need to do anything, just let it do its job.

like image 43
Seth Carnegie Avatar answered Nov 15 '22 18:11

Seth Carnegie