Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/heroku/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 设置std::vector大小的正确方法_C++_Stl_Stdvector - Fatal编程技术网

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

C++ 设置std::vector大小的正确方法,c++,stl,stdvector,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 <<

据我所知,
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;
}
我这样做的原因是,我保留了一定大小的缓冲区,然后通过
recv()
将内存传递给套接字。由于我必须将内存作为指针传递,因此无法根据
recv
返回的内容调整向量大小。 现在,当接收到的字节数小于缓冲区时,我会认为我可以以某种方式调整向量的大小,因此当我将其传回时,调用方可以执行
v.size()
和receive返回的元素数


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

recv
直接进入缓冲区,大致如下:

std::vector< unsigned char > buffer( 1024 );
buffer.resize( recv( &buffer[0], buffer.size() ) );
std::vector缓冲区(1024);
resize(recv(&buffer[0],buffer.size());
根据recv是否可以返回错误代码,您可能必须在调整大小之前进行检查

v.reserve(n)
将容量设置为
n

m = recv(s,&v[0],n,0)

v.resize(m)
将向量大小设置为recv得到的大小。

您的操作顺序错误

  • 调整大小
    至您希望缓冲区接受的最大大小
  • 存储数据(必须小于向量大小)
  • 将大小调整为实际数据大小
  • “数据消失”的问题是因为当你第一次复制数据时,你的向量没有大小限制的容量(即预先保留的内存,实际上没有使用它来保存数据)。当您再次
    reserve
    时,大小仍然为0,因此向量可以自由优化数据副本,因为它知道它必须只保留第一个
    size()
    元素(即0)

    换言之:

    • capacity()
      =在不触发重新分配的情况下,可以将多少数据放入向量中
    • size()

    此外,通过当前的
    size()
    访问向量元素是一种未定义的行为(它似乎适用于整数类型,但考虑未初始化的对象会发生什么…)。不要这样做。

    当您从vector的缓冲区第一个字节开始将某些内容复制到内存位置时,那么vector不会意识到这一点,也不会更新其内部大小计数器。使用vector的assign()或insert()方法将缓冲区复制到vector


    reserve()不会减少以前保留的容量。这就是为什么在最后一行中,您仍然可以看到50,但是您将其减少到20。

    如果您之前没有设置大小,您将永远看不到
    recv
    得到了什么。(当然,您还有未定义的行为。)这将保证数据在调整大小过程中不会丢失?因为这是我在短样本中用memcpy模拟的。当我调用receive时,操作系统会将套接字中的数据放入缓冲区,我知道向量无法确定这是多少。这就是为什么我需要在之后调整size(),以便向量知道它包含多少元素,但它显然不应该在过程中丢失数据,因为向量实现只关心已知元素。@Devolus:向量初始化为包含1024个元素,因此,它已经知道有1024个有效元素(其中
    recv
    写入)
    resize
    只会将元素计数更正为实际使用的元素,并(可能)修剪使用的内存。@MatteoItalia
    resize
    无法重新分配,除非它需要,因此它无法使缓冲区变小。在C++11中,有一个函数
    std::vector::shrink_to_fit
    ,可以用来减少使用的内存,也可以执行类似于
    std::vector(v.begin(),v.end())的操作。swap(v)。谢谢,这确实是正确的答案,我在调试器中用我的测试程序验证了它。现在我也明白了原因。:)这也适合我的实现模型,因为我在开始时不使用构造函数,但希望手动设置大小。
    
    m = recv(s,&v[0],n,0)