views:

303

answers:

3

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 http://stackoverflow.com/questions/688471/variable-sized-struct-c He was using a char array, and I'm using a vector though.

+5  A: 

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

JaredPar
ok that makes sense, so can it be dereferenced?
devin
+1  A: 

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
David Seiler
this is great -- I didn't think this approach would work.
devin
Note that the two declarations (c-struct and hier) are different.
bill
A: 

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

Warrior