正确的方法来设置std :: vector的大小

Dev*_*lus 3 c++ stl stdvector

从我读到的,std::vector是与需要连续内存字节数组的c函数接口时使用的适当结构.但是我想知道如何在某些情况下确定阵列的大小

我写了一个小样本程序来说明我的意思.

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;
}
Run Code Online (Sandbox Code Playgroud)

输出(不太令人惊讶):

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
Run Code Online (Sandbox Code Playgroud)

我这样做的原因是,因为我保留了一定大小的缓冲区,然后将此内存传递给套接字recv().由于我必须将内存作为指针传递,因此无法根据recv返回值调整矢量大小.现在当收到的字节数小于缓冲区时,我原以为我可以以某种方式调整向量的大小,所以当我传回它时,调用者可以做到v.size()并且接收返回的元素数量也是如此.

当我查看上面例子中的数据时resize(),正确调整使用缓冲区的大小,但数据消失了.那么我真的必须将内存单独复制到一个新的向量中才能获得正确的大小吗?这听起来像是一个非常不必要的开销.或者是否有某种方法可以告诉向量当前应该保留多少个元素?

sya*_*yam 6

你做的事情是错误的.

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

您的"数据消失"问题是因为当您第一次复制数据时,您的向量只有大小的容量(即预先保留的内存而不实际使用它来保存数据).当你reserve再次,大小依然是0,所以矢量可以自由地优化了数据复制,因为它知道它必须只保留第一size()要素(即0).

换一种说法:

  • capacity() =您可以在不触发重新分配的情况下将多少数据放入向量中.
  • size()=你真正使用了多少数据(并且向量将保留重新分配的数据)

更重要的是,访问其当前的向量元素size()是未定义的行为(它可能看起来与整数类型一起工作,但考虑未初始化对象会发生什么......).不要那样做.