简体   繁体   中英

Correct way to set the size of a std::vector

From what I read, std::vector is the appropriate structure to use when interfacing with c function requiring a contiguous memory byte array. However I was wondering how I can determine the size of the array in some cases

I have written a small sample program to illustrate what I mean.

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;
}

The output is (not much surprising):

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

The reason why I did this is, because I reserve a buffer of a certain size and then pass this memory to a socket via recv() . Since I have to pass the memory as a pointer, there is no way that the vector size gets adjusted according to what recv returns. Now when the received number of bytes is smaller then the buffer, I would have thought that I can somehow adjust the size of the vector, so when I pass it back, the caller can do v.size() and the the number of elements aka returned by receive.

When I looked at the data from the above example, when using resize() the size of the buffer is adjusted correctly, but the data is gone. So do I really have to copy the memory individually into a new vector just to get the correct size? This sounds like a really unnecessary overhead to me. Or is there some way to tell the vector how many elements it currently is supposed to hold?

You're doing things in the wrong order.

  1. resize to the max size you want your buffer to accept.
  2. Store the data (which must be smaller than the vector size).
  3. resize to the real data size.

Your problem of "disappearing data" is because when you copy the data the first time, your vector has no size only capacity (ie. pre-reserved memory without actually using it to hold data). When you reserve again, the size is still 0 so the vector is free to optimize out the data copy since it knows it must only keep the first size() elements (ie. 0).

In other words:

  • capacity() = how much data you could put in the vector without triggering reallocation.
  • size() = how much data you're really using (and the vector will keep only that data across reallocations)

What's more, accessing the vector elements past its current size() is Undefined Behaviour (it may appear to work with integral types but think about what would happen with uninitialized objects...). Don't do that.

recv straight into the buffer, something along the lines of:

std::vector< unsigned char > buffer( 1024 );
buffer.resize( recv( &buffer[0], buffer.size() ) );

Depending on if recv can return error codes you might have to check before resizing.

v.reserve(n) to set the capacity to n .

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

v.resize(m) to set the vector size to what recv got.

When you copy something to a memory location starting from vector's buffer first byte - then the vector is not aware of this and will not update its internal size counter. Use vector's assign() or insert() methods to copy the buffer to the vector.

reserve() doesn't decrease the capacity previously reserved. That is why in the last line you still see 50 nevertheless you decreased it to 20.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM