jeremyb
jeremyb

Reputation: 71

implement a pointer to a variable sized structure

I'm trying to parse returned information that can have a variable amount of data in a structure. I'm not sure how to do this efficiently, I wrote a class that contains each variable as a function and that function returns the data by calculating the appropriate offset however its not very manageable, there must be a better way. I've read about vectors (not much experience with them) but when I add them to a structure it adds additional padding which shifts all the variables over.

for example:

struct info_t {
   UINT32 signature;
   UINT32 elements[NUM_ELEMENTS];
   UINT32 options;
};

NUM_ELEMENTS is dynamically generated, and only known at runtime, the elements variable must be exactly NUM_ELEMENTS in size or the options variable will have the wrong offset.

I'm happy if I can initialize the structure pointer when its needed, but C++ won't let me get past having an unknown NUM_ELEMENTS variable during compile. Any ideas? Thanks.

Upvotes: 1

Views: 188

Answers (5)

Jørgen Fogh
Jørgen Fogh

Reputation: 7656

I assume that info_t is the format of the data you are trying to parse, so you can't change it.

Is there any particular reason why using the wrapper class isn't manageable? It seems like exactly the sort of problem where OOP is useful. If you wan't a class where the interface is compatible with info_t you could use the following layout:

struct info_t {
   UINT32 &signature;
   UINT32 * const elements;
   UINT32 &options;
};

You must then create a constructor which sets the fields to point to the correct locations in your input data.

If your input data is given as a pointer to an array of UINT32s, the constructor could look something like this:

info_t(UINT32 *data, size_t number_of_elements) :
    signature (*data),
    elements (data+1),
    options (*(data+number_of_elements+1)) {}

If you want data to be deallocated when the info_t instance goes out of scope you can do that in the constructor.

Upvotes: 0

umlcat
umlcat

Reputation: 4143

A picture (of the code) is more than a thousand words:

// --> do not instantiate a static variable of these:

struct info_t_headerstruct {
   UINT32 signature;
   UINT32 options;
   UINT32 num_elements;
   // no elements !!!
};

// --> do not instantiate a static variable of these, either:

// header plus variable elements
struct info_t_struct {
   info_t_headerstruct header;
   UINT32 elements[65535]; 
};

// --> you will use this type instead:

typedef
  info_t_struct* info_t_ptr;

info_t_ptr generate(size_t variableqty)
{
  size_t HowManyBytes = (sizeof(info_t_headerstruct) + (sizeof UINT32  * variableqty));
  info_t_ptr Result = malloc(HowManyBytes);
}

// ...

void doSomething(info_t_ptr dataptr)
{
  dataptr = generate(5);
  // ...
}

These is one those cases, where you may want to get rid off the "everything is a class / object" idea. I usually use "struct" in C++ same way as in "plain C", as data and not a class / object.

As mentioned in a previous answer. You should move the elements or variable data to the footer of the data type.

You also have to add a field that stores the quantity of items. The type is declared with a very big qty. of items, but, never, make a real variable of it.

You will work with a pointer of the structure, no the structure itself.

Some [university project / company] non-standard versions of "pascal" or "plain C" supported this kind of feature, in the syntax.

Upvotes: 0

MRAB
MRAB

Reputation: 20664

Try writing a wrapper class which takes the data and provides member functions to access the data in a nice clean way, and then see how fast it is. It may already be fast enough.

Upvotes: 1

Puppy
Puppy

Reputation: 146968

Normally, you put the variable length values at the end, and then you would pull it out as an array and allocate it in a vector, for example. This kind of code is usually not used in C++.

Upvotes: 2

Alok Save
Alok Save

Reputation: 206566

Variable length arrays(VLA) are not supported by C++ standard.
C++ provides std::vector for that.

Upvotes: 2

Related Questions