Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Array/table declaration in C with variable lengths in element entries

I need to define a table that contain some values of variable lengths.
I preferably want to declare it in one go since it’s related to constants that will never change.
I am checking if I can avoid a dynamic solution i.e. using malloc and set it up in code.

The code below will only serve as pseudo-code of what I want to achieve. It does not work.
i.e.

typedef struct myelems {
  char* name;
  int count1;
  int** values1;
  int count2;
  int** values2;
} myelems;

myelems arr[] = {
  {"a", 3, {1, 2, 3}, 1, {42} },
  {"b", 2, {123, 321},  3, {99, 88, 77} },
   // other elements here. . .
  {"x", 0, NULL,            0 , NULL}
};

In this example "a" will contain 3 entries in values1 and 1 entry in values2 such that

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

arr[0].values1[0] = 1
arr[0].values1[1] = 2
arr[0].values1[2] = 3
arr[0].values2[0] = 42

"b" will contain 2 entries in values1 and 3 in values2 such that

arr[1].values1[0] = 123
arr[1].values1[1] = 321
arr[1].values2[0] = 99
arr[1].values2[1] = 88
arr[1].values2[2] = 77

and "x" have 0 entries in both values1 and values2

I hope this is not a silly question but I just can’t find if it is not supported or if it is… if it is how should I do it?

Thanks for anything!

>Solution :

If compound literals are an option you can:

#include <stdio.h>

typedef struct myelems {
    char* name;
    int count1;
    int* values1;  // Notice a single star
    int count2;
    int* values2;  // Notice a single star
} myelems;


int main(void)
{
    myelems arr[] = {
        {"a", 3, (int[]){1, 2, 3}, 1, (int[]){42}},
        {"b", 2, (int[]){123, 321}, 2, (int[]){99, 88, 77}},
        // other elements here. . .
        {"x", 0, NULL, 0 , NULL}
    };
}

Your approach seems a bit dangerous (prone to errors) because you need to hardcode the number of elements in count1 and count2. Let the compiler count for you, with a little help of the preprocessor:

#define MAKE_INTS(...) \
    sizeof((int[]){__VA_ARGS__}) / sizeof(int), (int[]){__VA_ARGS__}

int main(void)
{
    myelems arr[] = {
        {"a", MAKE_INTS(1, 2, 3), MAKE_INTS(42)},
        {"b", MAKE_INTS(123, 321), MAKE_INTS(99, 88, 77)},
        // other elements here. . .
        {"x", 0, NULL, 0 , NULL}
    };
}

MAKE_INTS(1, 2, 3) expands to 3, (int[]){1, 2, 3}.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading