Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

alloc a struct with zero length array using new

In C (using gcc) I can declare a variable length struct as below:

typedef struct ProtocolFrame
{
     uint8_t      op;
     uint32_t     address;
     uint16_t     size;
     uint8_t      payload[0];
} ProtocolFrame;

then I can alloc different frame:

ProtocolFrame *frA;
ProtocolFrame *frB;

frA = malloc(sizeof(ProtocolFrame) + 50);
frB = malloc(sizeof(ProtocolFrame));

In this example frA has a payload field as big as 50 bytes, and frB has no payload

Can I do the same thing in C++ using the new operator?

like image 207
mastupristi Avatar asked Dec 23 '10 10:12

mastupristi


People also ask

Can we create array of length zero?

Yes, you can create arrays of any type with length zero.

What is zero size array in C?

Zero length arrays are described as being an IBM Extension enabled by the *EXTENDED compiler option (aka -qlanglvl=extended when using ixlc). According to the compiler output *EXTENDED is in effect (which is why char d[]; is being accepted as a flexible array).

Can an array have zero length Java?

If you have a function that takes an array, and you want to give it an array with nothing in it, you pass an zero-length array. If you read an array from an external source, and it happens to not have any items, you'll get an zero-length array.

Why do some structures end with an array of size 1?

Some Windows structures are variable-sized, beginning with a fixed header, followed by a variable-sized array. When these structures are declared, they often declare an array of size 1 where the variable-sized array should be.


1 Answers

template<size_t s>
struct ProtocolFrame
{
     uint8_t      op;
     uint32_t     address;
     uint16_t     size;
     uint8_t      payload[s];
} ProtocolFrame;

// specialize for no payload
template<>
struct ProtocolFrame<0>
{
     uint8_t      op;
     uint32_t     address;
     uint16_t     size;
} ProtocolFrame;

ProtocolFrame<50> *frA = new ProtocolFrame<50>;
ProtocolFrame<0> *frB = new ProtocolFrame<0>;

To decide what is the size at runtime you could use placement-new operator in cooperation with std::malloc:

void *buffer = std::malloc(sizeof(ProtocolFrame)+50);
ProtocolFrame *frA = new (buffer) ProtocolFrame;

You can read also this article on the codeproject.com which is contain the full sample.

like image 196
Kirill V. Lyadvinsky Avatar answered Oct 01 '22 21:10

Kirill V. Lyadvinsky