Mat*_*ain 4 c++ string garbage-collection vector
我试图弄清楚为什么以下 C++ 代码在 libstdc++ 中运行良好,但在 libc++ 中结果却c_str()变得垃圾。
该代码只是使用 构建一个字符串向量savedstrings.push_back("blah"),并且在将每个字符串添加到该向量后,立即savedstrings.back().c_str()将其添加到一个单独的向量const char*。
所以每个const char*应该指向savedstrings向量中相应的字符串。这对于 libstdc++ 来说工作得很好,但是对于 libc++ 来说,随着后面的向量的添加,向量const char*开头的cstrs向量开始变成垃圾。
我不确定我是否明白这里发生了什么。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;
Run Code Online (Sandbox Code Playgroud)
如果在 中进行任何重新分配savedstrings,则指向基础字符串数据的指针可能会变得无效。取消引用此类指针将产生未定义的行为。
您可以通过保留适量的容量来避免重新分配:
vector<string> savedstrings;
savedstrings.reserve(10);
Run Code Online (Sandbox Code Playgroud)
下面的示例显示了当您将元素推入 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;
}
}
Run Code Online (Sandbox Code Playgroud)
输出:
1
2 # re-allocation
4 # re-allocation
4
8 # re-allocation
8
8
8
16 # re-allocation
16
Run Code Online (Sandbox Code Playgroud)