0

Is it possible to create a struct containing two dynamically size arrays in c?

I have something like this:

#define MAX_DATA 512

    struct Address {
    int id;
    int set;
    char name[MAX_DATA];
    char email[MAX_DATA];
};

I'd like MAX_DATA to be defined at run time.

I have seen the struct hack:

How to include a dynamic array INSIDE a struct in C?

But I think this only works for one field per struct?

This code is from http://c.learncodethehardway.org/book/ex17.html

The extra credit section near the bottom of that page contains the bit about changing the sizes to be dynamic.

5
  • Sure, you just change the arrays to pointers, and then you need one call to malloc for each dynamically sized array... Commented Apr 10, 2014 at 10:26
  • 1
    I really need to read the tags first, I was almost suggesting "use a std::vector" Commented Apr 10, 2014 at 10:27
  • It's not a hack but clearly mentioned in the standard. It's called flexible array member or zero-length array. Commented Apr 10, 2014 at 10:46
  • 1
    IMHO cut your losses and use a normal malloc instead of a struct hack , you'll thank yourself for it a few years later when you maintain the code. Commented Apr 10, 2014 at 10:53
  • @MattMcNabb I don know that a "normal" malloc (i.e. three mallocs) is more maintainable. Any complexity from sharing one buffer can usually be encapsulated inside the function that creates Address instances. And using one buffer means that an Address can be freed using a normal free(). Commented Apr 11, 2014 at 3:41

4 Answers 4

3

I once did this:

struct Thing {
    int Number;
    char *MoreBytes;
    char Bytes[]
}


Thing *MakeThing(int nBytes, int nMoreBytes) 
{
    Thing *th = malloc(sizeof(Thing) + nBytes + nMoreBytes);
    // Error checking is for grrrlz.

    th->Number = 42;
    th->MoreBytes = th->Bytes + nBytes; 

    return th;
}

Thus the array th->Bytes actually holds both "arrays", and the pointer th->MoreBytes tells us where one array ends and another begins.

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

Comments

0

It works (at least for GCC 4.7.2) if you put your struct Address definition in a function, like this:

#include <stdio.h>
#include <stdlib.h>

int
main(int argc, char *argv[])
{
    int len = atoi(argv[1]);

    struct Address {
        int id;
        char name[len];
        int set;
        char email[len];
    };

    printf("sizeof(struct Address) = %zu\n", sizeof(struct Address));
    exit(EXIT_SUCCESS);
}

Testing:

$ ./a.out 10
sizeof(struct Address) = 32
$ ./a.out 20
sizeof(struct Address) = 48

2 Comments

Again, that's not the struct hack. Ask yourself what happens when len becomes very large. Or you want the struct to live beyond the scope in which it was declared.
@DavidHeffernan Yeah, it is not struct hack, but something like variable length array (VLA). And it may not work or work well for those situations you just mentioned.
0
struct Address 
{
int id;
int set;
char *name;
char *email;
};

Now in the main() function, Use some variable, lets say len to store length of the array, and dynamically allocate required memory using malloc().

int len;
struct Address Add;
printf("Enter the lenght of the array you want?");
scanf("%d",&len);
Add.name=(char *)malloc(len); 
Add.email=(char *)malloc(len);

otherwise you can add len as the member of the struct Address

struct Address 
{
int id;
int set;
int len;
char *name;
char *email;
};

Now in main()

struct Address Add;
printf("Enter the lenght of the array you want?");
scanf("%d",&Add.len);
Add.name=(char *)malloc(Add.len); 
Add.email=(char *)malloc(Add.len);

1 Comment

That's not the struct hack
0

You can do this using the struct hack, now known as a flexible array. It just requires you to pack both arrays into the flexible part of the struct.

Suppose that you want the arrays to be of length N and M respectively. Then allocate a flexible array as if you were allocating a single array of length N+M. Then use indices 0..N-1 for the first array, and indices N..N+M-1 for the second array.

2 Comments

I think this answer would be clearer if it defined the "struct hack".
@AdrianRatnapala I'm not sure I really want to add yet another explanation of the struct hack to the canon. There's a perfectly good Q on the topic linked in the question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.