Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Allocating struct with variable length array member

I know I can do new char[n] to create an array of n chars. This works even when n is not a compile time constant.

But lets say I wanted a size variable followed by n chars:

My first attempt at this is the following:

struct Test
{
  std::size_t size;
  char a[];
};

However it seems new Test[n] doesn't do what I expect, and instead allocates n sizes.

I've also found that sizeof(std::string) is 4 at ideone, so it seems it can allocate both the size and the char array in one block.

Is there a way I can achieve what I described (presumably what std::string already does)?

like image 661
Clinton Avatar asked Oct 03 '11 23:10

Clinton


People also ask

Can a struct have a member variable that is an array?

A structure may contain elements of different data types – int, char, float, double, etc. It may also contain an array as its member.

How do I get the length of an array of structures in C++?

In C++, we use sizeof() operator to find the size of desired data type, variables, and constants. It is a compile-time execution operator. We can find the size of an array using the sizeof() operator as shown: // Finds size of arr[] and stores in 'size' int size = sizeof(arr)/sizeof(arr[0]);

Can we declare array inside structure?

For the structures in C programming language from C99 standard onwards, we can declare an array without a dimension and whose size is flexible in nature. Such an array inside the structure should preferably be declared as the last member of structure and its size is variable(can be changed be at runtime).

What is struct hack?

“Struct Hack” technique is used to create variable length member in a structure. In the above structure, string length of “name” is not fixed, so we can use “name” as variable length array. Let us see below memory allocation. struct employee *e = malloc(sizeof(*e) + sizeof(char) * 128);


1 Answers

While you can do this (and it was often used in C as a workaround of sorts) it's not recommended to do so. However, if that's really what you want to do... here's a way to do it with most compilers (including those that don't play nicely with C99 enhancements).

#define TEST_SIZE(x) (sizeof(Test) + (sizeof(char) * ((x) - 1)))

typedef struct tagTest
{
    size_t size;
    char a[1];
} Test;

int elements = 10; // or however many elements you want
Test *myTest = (Test *)malloc(TEST_SIZE(elements));

The C specifications prior to C99 do not allow a zero-length array within a structure. To work around this, an array with a single element is created, and one less than the requested element count is added to the size of the actual structure (the size and the first element) to create the intended size.

like image 200
Adam Maras Avatar answered Oct 24 '22 23:10

Adam Maras