2

How does one build a struct with an array that can be set differently for each struct, ideally by a parameter? The application being a single data type that supports arrays of different, but fixed lengths

My attempt looks somehting like this, which obviously didnt compile:

struct Data_struct(n)
{
    int xData[n];
    int test;
};
2
  • Err, this int[n] xData; wouldn't compile any ways. Commented Mar 4, 2016 at 17:03
  • @alk Yeah i realized that pretty quickly. In my defense, it was 5pm on a Friday :P Commented Mar 7, 2016 at 10:57

4 Answers 4

3

The only method available is to use a flexible array member.

struct Data_struct {
    int test;
    int xData[];
};

You would then allocate space for this using malloc():

int n = 4;
struct Data_struct *s = malloc(sizeof(struct Data_struct) + n * sizeof(int));

Note that we had to explicitly allocate additional space for the flexible array.

Sign up to request clarification or add additional context in comments.

2 Comments

Flexible array members have incomplete type, and so the sizeof operator may not be applied. See gcc.gnu.org/onlinedocs/gcc/Zero-Length.html
Also please note, that the "array" has to be the last member of the structure, which leads to the implicit constrain that only one such "array"s per struct is possible.
2

You can dynamically allocate the array

struct Data_struct
{
    int * xData;
    int test;
};

....

s.xData = calloc(size, sizeof(int))

and remember to free xData when finished

3 Comments

I'm not sure why this attracted a down-vote - it's certainly a valid answer ?
Not my downvote, but with your solution the Data_Struct is no more a single piece of contiguous memory.
@MichaelWalz: true, but I don't think there's a single perfect solution - it depends on various factors, so this might be a better solution in some cases (e.g. if you want an array of such structs).
1

Normally you would define a variable length array at the end of the struct, and then fix up the size at run-time, e.g.

typedef struct
{
    int test;
    int xData[1];
} Data_struct;

To allocate a struct such as this with a size of n for xData you'd do soemthing like this:

Data_struct * s = malloc(sizeof(Data_struct) + (n - 1) * sizeof(int));

6 Comments

thing to remember here is that you are fooling the compiler. sizeof(DataStruct) will be wrong, passing it by value will fail.
@pm100: yes, that's true - I don't know if C99's flexible array member (see Bill's answer) is any improvement in this regard ?
"Struct hack" has been formalized to flexible array member in C99. I would consider this approach deprecated.
@user3528438: yes, I went for an old skool C89 solution, but Bill's C99 solution is probably preferable in most cases, unless you're stuck with an old compiler without C99 support (still the case for some embedded tool chains !).
Don't you want an array with zero elements? Then you don't need (n-1), just n in your calloc.
|
1

One might call this ugly but here goes. Use a #define

#define foo(n) struct Data_struct##n { int test; int xData[n]; }

foo(20);

struct Data_struct20 abc;

The foo(20) defines a structure with n = 20 characters. You could use another #define for the allocation of space if you wish.

3 Comments

OP specifically asks for a "a single data type that supports arrays of different, but fixed lengths".
@PaulR. But you already wrote that answer. Mine doesn't require a malloc which may be useful.
The problem is that it doesn't answer the OP's question as posed, since he wants a single data type - your answer might therefore cause confusion for someone else coming along and reading this question later. So I have to down-vote, regrettably.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.