How to Get the Address of the Std::Vector Buffer Start Most Elegantly

How to get the address of the std::vector buffer start most elegantly?

Well, you can remove one set of parens:

&buffer[0]

but that is the common, idiomatic way of doing it. If it really offends you, I suppose you could use a template - something like:

template <typename T> 
T * StartOf( std::vector <T> & v ) {
return &v[0];
}

std::vector and c-style arrays

Are there implementation guarantees in the stl that vector is, internally, consecutive in memory?

As of C++03, yes, a vector is guaranteed to use contiguous storage.
(In C++98, there was an accidental loophole so an implementation could hypothetically use non-contiguous storage, but it was fixed in the 2003 revision of the standard - and no implementation actually used non-contiguous storage because it'd be a terrible idea)

Can I safely cast a std::vector to int* and expect that to work?

The usual way is &v[0]. (&*v.begin() would probably work too, but I seem to recall there's some fluffy wording in the standard that makes this not 100% reliable)

No. Why would you expect that to work? A vector is a class. It is not a pointer. It just contains a pointer.

In the case of a vector of vectors, can I still assume this holds true? I would expect the vector to hold other state data, or alignment issues, or maybe something else...

The vector behaves the same whatever you store in it. If you make a vector of vectors, you end up with an object which contains a pointer to a heap-allocated array, where each element is an object which contains a pointer to a heap-allocated array.

As for how you should approach this, it depends on a lot of factors. How big is your total dataset? You might want to have the entire table allocated contiguously. With a vector of vectors, each row is a separate allocation.

Use std::vector in WaitForMultipleObjects()

Preferably, if you've got an up to date version of STL, you should use:

WaitForMultipleObjects(events.size(), events.data(), true, INFINITE);

With older STL's, you can use &events[0] if .data() isn't available as a method on vector.

Prettier syntax for pointer to last element, std::vector?

int* ptrToLastOne = &vec.back(); // precondition: !vec.empty()

How do I get char * from vectorchar?

As long as you don't resize the vector in any way, you can use &vbuffer[0] as a pointer to the array. There are many operations that will invalidate pointers to a vector though, make sure you don't call any of them while you have a pointer in use.

How to initialize std::vector from C-style array?

Don't forget that you can treat pointers as iterators:

w_.assign(w, w + len);

c++ vectorchar and sockets

std::vector<char> b(100); 
send(z,&b[0],b.size(),0);

Edit: I second Ben Hymers' and me22's comments. Also, see this answer for a generic implementation that doesn't try to access the first element in an empty vectors.

Is there an elegant way of parsing a byte buffer of dynamic length into a struct?

A example of how i handle it in my code.

class packet
{
public:
packet(absl::Span<const char> data)
{
auto current = data.data();
std::memcpy(&length_, current, sizeof(length_));
std::advance(current, sizeof(length_));

vec_.reserve(length_);
vec_.assign(current, current + length_);
}

//public stuff as needed

private:
std::vector<char> vec_{};
uint16_t length_{};
//...other members
};

to deserialize the object all you have to do is something like packet{{data_ptr, data_len}};

I have a helper function that removes a lot of the duplication and boilerplate of deserializing multiple members, but its not important to the example.

This should fit nicely into your read method

MessageType Read(){
return MessageType{{rawBuffer, sizeof msg}};
}

A more elegant way to use recv() and vectorunsigned char

This technique is leak-safe, quite clean and preferable. Using std::vector is the recommended way of implementing a variable-length buffer in C++.

If you find that not all data fits into the vector - no problem, just resize it to bigger size and pass the address of the section that follows the already-filled part.

Using reserve() is not a very good idea - it doesn't affect what size() returns, so you will lose convenience and likely will gain no advantages.



Related Topics



Leave a reply



Submit