c++11 - Address of an instance emplaced to std::vector is invalid -


i have 2 std::vectors:

  • to first vector, emplace instance
  • to second vector, want store address of instance emplaced

but not work, i.e., stored address differs emplaced instance's address.

if matters @ all, i'm on linux , using g++ 5.1 , clang 3.6 -std=c++11.

here's working example illustrate problem.

#include <iostream> #include <vector>  struct foo {   foo(int a1, int a2) : f1(a1), f2(a2) {}    int f1;   int f2; };  int main(int, char**) {   std::vector<foo> vec1;   std::vector<foo*> vec2;    int num = 10;   (int = 0; < num; ++i) {     vec1.emplace_back(i, * i);      // want store address of *emplaced* instance...     vec2.push_back(&vec1.back());   }    // same   std::cout << "size 1: " << vec1.size() << std::endl;   std::cout << "size 2: " << vec2.size() << std::endl;   // same me   std::cout << "back 1: " << &vec1.back() << std::endl;   std::cout << "back 2: " << vec2.back() << std::endl;   // typically differ ?   std::cout << "front 1: " << &vec1.front() << std::endl;   std::cout << "front 2: " << vec2.front() << std::endl;    (int = 0; < num; ++i) {     std::cout << + 1 << "th" << std::endl;     // same last several (size % 4) me     std::cout << "1: " << &vec1[i] << std::endl;     std::cout << "2: " << vec2[i] << std::endl;   } } 

questions

  • is correct behavior ? guess it's caused storing address of temporary instance want know whether it's permitted standard (just curious).
  • if above true, how work around ? resolved changing first 1 vector<unique_ptr<foo>> there idiomatic way ?

two options:

1) can fix test. need in test preallocate enough memory first with

 vec1.reserve(10); 

well, implementation details std::vector. more , more items added std::vector needs more space them. , space must contigious. when there not enough space new element std::vector allocates bigger block of memory, copies existing elements it, add new element , frees block of memory used before. result addresses stored in vec2 might become invalid.

however, if preallocate enough memory 10 elements code correct.

or, since reserving memory sort of tricky thing do

2) use std::deque since insertion , deletion @ either end of deque never invalidates pointers or references rest of elements (http://en.cppreference.com/w/cpp/container/deque) , forget problem invalidated addresses. no need reserve memory.


Comments

Popular posts from this blog

c# - Validate object ID from GET to POST -

node.js - Custom Model Validator SailsJS -

php - Find a regex to take part of Email -