C++中std中的vector和string中的指针问题?

cup11
  • 15

C++中,char*int[]等类型都有所局限,刚好我是从Python转到C++的,所以比较喜欢用std::stringstd::vector
然而,之后我又知道了指针问题。指针确实速度更快(我记得测过,大约快3倍),不过std::stringstd::vector既然是动态的内存管理,就必然会引发一些问题。因此我要提以下几个问题:

  1. std::vector元素类型是定长类型的情况下用下标、iter还是用指针?各自的优缺点是什么?

    std::vector<short> vec = {1, 3, 9, 2, 4, 3, 7, 3, 9, 5};
    for (int i=0; i<10; i++) {
     vec[i] *= 2;
    }
    std::vector<short> vec = {1, 3, 9, 2, 4, 3, 7, 3, 9, 5};
    std::vector<short>::iterator iter = vec.begin();
    while (iter != vec.end()) {
     *(iter++) *= 2;
    }
    std::vector<short> vec = {1, 3, 9, 2, 4, 3, 7, 3, 9, 5};
    short *p = &vec[0];
    for (int i=0; i<10; i++) {
     *(p++) *= 2;
    }
  2. 针对std::vector<std::string>std::vector<std::vector>等嵌套的动态内存管理的情形,我除了用[]访问还有什么更快且安全的办法?
  3. 何时std::vectorstd::string才会出现指针的问题?原理是什么?迭代器呢?

我可能需要的回答:三种方法对于两种不同情况(1、2)各自的运行时间(时间复杂度等)、稳定性(会不会出意外情况)。

回复
阅读 1.2k
2 个回答

我想了好一会,发现居然完全不知道怎么回答....
只能说,对于初学者,

  1. 能不碰指针就不碰指针,
  2. 代码的可读性比钻牛角尖的性能优化重要

所以,2022年我们都是这么操作vector的

for (auto& i : vec) {
    i += 1;
}

首先是一个原则:对于C++这类编译器的优化行为很重的语言,不要随便“幻想”它的实际行为(特别是对于初学者),也不要过早进入细节优化。优化应当是基于profile结果的。

逐个回复:
1:很可能编译器优化之后的结果都是一样的,特别是对于问题中简单的循环访问的情况。
2:没有。实际上对于标注库的vector,方括号操作符在优化模式下是无保护的,执行代价应当会被优化到和裸数组下标访问一样。
3:什么叫“指针问题”?这不是一个好的描述。实际上更好的描述是“内存问题”。通常来讲,这类容器会有自动维护内部存储的特性,那么如果你在别处保存一个指向它元素的指针,在内部存储发生变化之后,很可能指针会指向非法区域,这大概是比较常见的“指针问题”。比如:

std::vector<int> data(10);
int* ptr = &data[3];
data.resize(10000); // 此时ptr很可能已经指向非法区域
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
宣传栏