根据我的阅读,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 它当前应该包含多少个元素?
最佳答案
你做事的顺序错了。
resize
到您希望缓冲区接受的最大大小。- 存储数据(必须小于 vector 大小)。
resize
到实际数据大小。
你的“数据消失”问题是因为当你第一次复制数据时,你的 vector 没有大小容量(即预留内存而不实际使用它来保存数据)。当您再次 reserve
时,大小仍然为 0,因此 vector 可以自由优化数据拷贝,因为它知道它必须只保留第一个 size()
元素(即. 0).
换句话说:
capacity()
= 您可以在不触发重新分配的情况下将多少数据放入 vector 中。size()
= 您实际使用了多少数据( vector 将只保留重新分配的数据)
此外,访问超过其当前 size()
的 vector 元素是未定义的行为(它可能看起来适用于整数类型,但请考虑未初始化的对象会发生什么......)。不要那样做。
关于c++ - 设置 std::vector 大小的正确方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16339479/