如何获取vector string的原始资源.
通常的做法
vector v; string s;
&v[0] 就可以获取原始资源的指针
s.c_str()就可以获取原始字符串数组的指针
因为c++标准要求vector中的元素按顺序存储在连续的空间中,所以定位找到第一个元素指针就能找到全部的元素.但问题是如果v是空的. 那么&v[0] 将返回一个野指针. 所以在使用&v[0]前要确保(!v.empty())
那问题是对于string类型的s,为什么不能通过&s[0]来获取头指针呢.
个人理解: 因为c++标准没有规定string中的元素一定是按顺序联系存放的. 所以有可能&s[0]取出的指针和&s[1]取出的指针不一定是挨着的. 但是string标准会提供一个c_str()函数,这个函数能够返回一个指针,指向连续的数据空间. 如果string的实现是不连续存放的,那么他的c_str()函数接口就会想办法复制一份数据到连续空间,并返回指针.
注意不能通过string的raw指针去修改数据
c_str()返回的指针是只读,不可写. 就上上面描述的,有可能string的实现是非连续存储. 当调用c_str()的时候, 是把非连续存储的数据放到了一份连续空间供你查看, 这个空间只是临时生成的.并不是string维护数据真正的地方.对他修改是没有意义的, string内部的维护信息并不认可这样的改动.如果用这种方式修改数据, 后续string的size, append等操作都会异常.
不要通过vector的raw指针去修改数据
一样的如果你通过raw指针越界了,此时的vector并不会帮你去扩容. 此时的越界会导致程序异常. 即使不越界, 你通过raw指针新加了一个数据,vector也不知道,他的size还是原来的大小.
如何把一个数组转化成vector
可以充分利用vector和数组都保证连续存储的特征.
int arrayInt[100] = { 0, };
int main()
{
for (int i = 0; i < 100; i++)
arrayInt[i] = i;
vector<int> vecInt;
vecInt.reserve(100);
vecInt.resize(100);
memcpy(&vecInt[0], arrayInt, 100 * sizeof(int));
}
需要注意的是,在执行memcpy前一定要保证vector中存在至少100个元素,否则执行memcpy就会异常.
更好的推荐代码是通过区间构造函数实现拷贝.
int arrayInt[100] = { 0, };
int main()
{
for (int i = 0; i < 100; i++)
arrayInt[i] = i;
vector<int> vecInt(arrayInt, arrayInt+100);
}
如何把一个char 数组转化成string
最好的方法还是利用string的区间构造函数实现
char arrayChar[26];
int main()
{
for (int i = 0; i < 26; i++)
arrayChar[i] = 'a'+i;
vector<int> vecInt(arrayInt, arrayInt+100);
std::string s(arrayChar, arrayChar + 26);
}
充分利用各个容器的区间构造函数,来实现容器数据向array的转换
假如有个旧的API只能处理数组, 但是数据被你维护在某个容器中,那么笨方法是, for_each每个元素,把每个元素放到新建的数组上,然后把数组传给这个API.
更好的方法是,通过区间构造函数,任何容器上的数据,都能转换成vector数据,而vector数据因为连续内存的设计,很容易兼容需要数组的接口.
网友评论