I need to craft a packet that has a header, a trailer, and a variable length payload field. So far I have been using a vector for the payload so my struct is set up like this:
struct a_struct{
hdr a_hdr;
vector<unsigned int> a_vector;
tr a_tr;
};
When I try to access members of the vector I get a seg fault and a sizeof of an entire structs give me 32 (after I've added about 100 elements to the vector.
Is this a good approach? What is better?
I found this post
Variable Sized Struct C++
He was using a char array, and I'm using a vector though.
The solution in the other SO answer is c-specific, and relies on the peculiarities of c arrays - and even in c, sizeof() won't help you find the "true" size of a variable size struct. Essentially, it's cheating, and it's a kind of cheating that isn't necessary in C++.
What you are doing is fine. To avoid seg faults, access the vector as you would any other vector in C++:
a_struct a;
for(int i = 0; i < 100; ++i) a.a_vector.push_back(i);
cout << a.a_vector[22] << endl; // Prints 22
Even though the vector type is inlined in the struct, the only member that is in the vector is likely a pointer. Adding members to the vector won't increase the size of the vector type itself but the memory that it points to. That's why you won't ever see the size of the struct increase in memory and hence you get a seg fault.
Usually when people want to make a variable sized struct, they do so by adding an array as the last member of the struct and setting it's length to 1. They then will allocate extra memory for the structure that is actually required by sizeof() in order to "expand" the structure. This is almost always accompanied by an extra member in the struct detailing the size of the expanded array.
The reason for using 1 is thoroughly documented on Raymond's blog
- http://blogs.msdn.com/oldnewthing/archive/2004/08/26/220873.aspx
i saw this implementation in boost..it looks really neat...to have a variable
length payload....
class msg_hdr_t
{
public:
std::size_t len; // Message length
unsigned int priority;// Message priority
//!Returns the data buffer associated with this this message
void * data(){ return this+1; } //
};
this may be totally un-related to the question, but i wanted to share the info