reference change when push_back

Hello,

I have a problem to push_back new elements to a vector.
When I push a new element, all the elements I added before become the same as the new element.

I use the same code in other places as well, but only in one place I have this problem.

I don't now why it happens. I also tried it with std::move, but it did not solve the problem.

I appreciate it if someone can help me.

Best,
M

1
2
3
4
5
  std::vector<const char*> n_vec;
  for (auto &p : p_vec)
  {
    n_vec.push_back(p.name().c_str());
  }
std::vector stores its elements in an array. The size of that array can be read using the capacity() function. If you insert more elements than can fit in the array it will allocate a new bigger array, move the elements from the old array to the new array, and keep using the new array instead. This means the elements will be stored in a new location in memory.

If you have a known upper limit on the number of elements that you will be storing in the vector you can avoid reallocations by explicitly specifying the size of the vector's internal array using the reserve() function.

http://en.cppreference.com/w/cpp/string/basic_string/reserve

You also need to be very careful when storing the pointer returned from c_str() because it can easily be invalidated if the string is modified. Have you considered storing std::string instead of const char* inside the vector?

http://en.cppreference.com/w/cpp/string/basic_string/c_str
You may push_back an invalid/temporary pointer. It depends on what p.name() returns. See:

http://www.cplusplus.com/reference/string/string/c_str/

The pointer returned may be invalidated by further calls to other member functions that modify the object.
Thank you for your reply.
p.name() restuns std::string.
That is probably a temporary variable like std::string name(). So, why don't you store the std::string?
because of I have to pass n_vec.data() to another function which is a function at the low level of a big package, not a good idea to change it.
If I use std::string instead of const char*, it won't be compiled because of that function.
When I push a new element, all the elements I added before become the same as the new element

this seems to suggest that all the existing pointers in n_vec are reassigned upon each push_back to point to the object owned by the latest entrant and might be due to what coder777 says about temporary variables but I'm wondering in that case std::move() might have worked but ...
I also tried it with std::move, but it did not solve the problem

I also expected that, but it did not work.

This is how I used std::move

std::vector<const char*> n_vec;
for (auto &p : p_vec)
{
n_vec.push_back(std::move(p.name().c_str()));
}
OP: can you post here entire program here or somewhere like pastebin?
std::move(...) has no effect in this case. It is a kind of cast that enables an rlvalue to be moved.

http://www.cplusplus.com/reference/utility/move/?kw=move


If I use std::string instead of const char*, it won't be compiled because of that function.
You need to explicitly allocate enough memory for the string and then copy the content.
Last edited on
Topic archived. No new replies allowed.