c_str() 结果从向量<string>变成垃圾与 libc++

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

本文关键字:string gt libc++ lt str 结果 向量      更新时间:2023-10-16

我试图弄清楚为什么以下C++代码在libstdc++中工作正常,但是对于libc ++,c_str()结果变成了垃圾。

代码只是使用 savedstrings.push_back("blah") 构建一个字符串向量,并且在每个字符串添加到向量之后,savedstrings.back().c_str() 被添加到一个单独的 const char* 向量中。

因此,每个const char*都应指向savedstrings向量中的相应字符串。这在libstdc++中工作正常,但是对于libc++,随着后面的添加,cstrs向量开头的const char*开始变成垃圾。

不确定我是否理解这里发生了什么。savedstrings向量是否会在添加新字符串时移动较早的字符串,从而使c_str()结果无效?我怎样才能阻止这种情况发生?

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;

如果在 savedstrings 中有任何重新分配,则指向底层字符串数据的指针可能会变得无效。取消引用此类指针将产生未定义的行为

您可以通过预留适量的容量来避免重新分配:

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

下面是一个示例,显示了当您将元素推入 is 时向量的容量如何增长(在某些 ubuntu x86_64 上为 g++ 4.7.3):

#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;
  }
}

输出:

1
2   # re-allocation
4   # re-allocation
4
8   # re-allocation
8
8
8
16  # re-allocation
16

c_str()返回的指针必须立即使用,不打算存储以供以后使用。