Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

c_str() results from vector<string> become garbage with libc++

I am trying to work out why the following C++ code works fine with libstdc++, but with libc++ the c_str() results become garbage.

The code simply builds a vector of strings using savedstrings.push_back("blah"), and right after each string is added to the vector, savedstrings.back().c_str() is added to a separate vector of const char*.

So each const char* should point to the corresponding string in the savedstrings vector. This works fine with libstdc++, but with libc++ the const char* at the start of the cstrs vector start to become garbage as the later ones are added.

I'm not sure I understand what is going on here. Is the savedstrings vector moving the earlier strings as new ones are added, thus invalidating the c_str() result? How can I stop this from happening?

vector<string> savedstrings;
vector<const char*> cstrs;

for (int i = 0; i < 10; i++) {
  savedstrings.push_back("blah");
  cstrs.push_back(savedstrings.back().c_str());
}

vector<string>::iterator si;
for(si=savedstrings.begin();si!=savedstrings.end();++si)
  cout << *si << endl;

vector<const char*>::iterator ci;
for(ci=cstrs.begin();ci!=cstrs.end();++ci)
  cout << *ci << endl;
like image 269
Matt Swain Avatar asked Oct 27 '25 12:10

Matt Swain


1 Answers

If you have any re-allocations in savedstrings, the pointers to the underlying string data may become invalid. De-referencing such pointers would yield undefined behaviour.

You can avoid re-allocations by reserving the right amount of capacity:

vector<string> savedstrings;
savedstrings.reserve(10);

Here's an example showing how a vector's capacity grows as you push elements into is (g++ 4.7.3 on some ubuntu x86_64):

#include <vector>
#include <iostream>

int main()
{
  std::vector<int> v;

  for (int i = 0; i < 10; ++i){
    v.push_back(0);
    std::cout << v.capacity() << std::endl;
  }
}

Output:

1
2   # re-allocation
4   # re-allocation
4
8   # re-allocation
8
8
8
16  # re-allocation
16
like image 142
juanchopanza Avatar answered Oct 29 '25 01:10

juanchopanza



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!