c++ - 设置 std::vector 大小的正确方法

标签 c++ stl stdvector

根据我的阅读,std::vector 是与需要连续内存字节数组的 c 函数接口(interface)时使用的适当结构。但是我想知道在某些情况下如何确定数组的大小

我写了一个小示例程序来说明我的意思。

int main(int argc, char *argv[])
{
    std::vector<unsigned char>v;
    unsigned char p[1024];

    sprintf((char*)&p[0], "%10d", 10);
    cout << "Size: " << v.size() << " Length: " << v.capacity() << endl;
    v.reserve(30);
    cout << "Size: " << v.size() << " Length: " << v.capacity() << endl;
    memcpy(&v[0], &p[0], 20);
    cout << "Size: " << v.size() << " Length: " << v.capacity() << endl;
    v.reserve(50);
    cout << "Size: " << v.size() << " Length: " << v.capacity() << endl;
    v.reserve(0);
    cout << "Size: " << v.size() << " Length: " << v.capacity() << endl;
    v.resize(20);
    cout << "Size: " << v.size() << " Length: " << v.capacity() << endl;
    v.resize(0);
    cout << "Size: " << v.size() << " Length: " << v.capacity() << endl;

    return 0;
}

输出是(不足为奇):

Size: 0 Length: 0
Size: 0 Length: 30
Size: 0 Length: 30
Size: 0 Length: 50
Size: 0 Length: 50
Size: 20 Length: 50
Size: 0 Length: 50

我之所以这样做,是因为我预留了一定大小的缓冲区,然后通过recv()将这 block 内存传递给socket。由于我必须将内存作为指针传递,因此无法根据 recv 返回的内容调整 vector 大小。 现在,当接收到的字节数小于缓冲区时,我想我可以以某种方式调整 vector 的大小,所以当我将它传回时,调用者可以执行 v.size() 以及接收返回的元素数量。

当我查看上述示例中的数据时,当使用 resize() 时,缓冲区的大小已正确调整,但数据消失了。那么我真的必须将内存单独复制到一个新的 vector 中才能获得正确的大小吗?这对我来说听起来像是一个非常不必要的开销。或者有什么方法可以告诉 vector 它当前应该包含多少个元素?

最佳答案

你做事的顺序错了。

  1. resize 到您希望缓冲区接受的最大大小。
  2. 存储数据(必须小于 vector 大小)。
  3. resize 到实际数据大小。

你的“数据消失”问题是因为当你第一次复制数据时,你的 vector 没有大小容量(即预留内存而不实际使用它来保存数据)。当您再次 reserve 时,大小仍然为 0,因此 vector 可以自由优化数据拷贝,因为它知道它必须只保留第一个 size() 元素(即. 0).

换句话说:

  • capacity() = 您可以在不触发重新分配的情况下将多少数据放入 vector 中。
  • size() = 您实际使用了多少数据( vector 将只保留重新分配的数据)

此外,访问超过其当前 size() 的 vector 元素是未定义的行为(它可能看起来适用于整数类型,但请考虑未初始化的对象会发生什么......)。不要那样做。

关于c++ - 设置 std::vector 大小的正确方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16339479/

相关文章:

c++ - std::vector::const_iterator 未指向所需数据

c++ - 带大括号的 std::vector init 调用复制构造函数两次

c++ - 编译器生成的构造函数

c++ - 用固定值初始化多维 vector

c++ - STL 列表添加和删除所选元素

c++ - 如何使用 map 从 CPP 中带有 vector 的文件中获取唯一值?

C++ 使用 reserve 和可能的 emplace_back 从文件中存储 vector<std::string>

c++ - 如何确定 cv::Mat 是否有零值?

c++ - 使用 ESC 键关闭 Carbon 模式对话框

c++ - 重绘屏幕并删除已经存在的内容