4

i would like create a array of structure which have a dynamic array :

typedef struct{
    float a;
    int b[];
}structure_t;

  n = ...;
  size_t dimstruct = sizeof(structure_t)+n*sizeof(int);
  structure_t * resultat = malloc(dimstruct);

How to create a dynamic array of this structure and contiguous in memory?

Thx!

Arkerone
  • 1,971
  • 2
  • 22
  • 35
  • 3
    Memory allocated by malloc is always contiguous. – Adriano Repetti Mar 26 '12 at 15:14
  • Yes, but the allocation of `b` will not be contiguous within the struct array. You'll have to repack your data to send with MPI, you can't force what you have to be contiguous. – tpg2114 Mar 26 '12 at 15:17
  • @tpg2114 what do you mean b is not contiguous? Arrays are contiguous. See http://stackoverflow.com/questions/2832970/does-c99-guarantee-that-arrays-are-contiguous In fact he could use b to pad data in his struct to make it aligned. – Adrian Mar 26 '12 at 15:19
  • 1
    It's possible to create the array of this structure and it's contigous? – Arkerone Mar 26 '12 at 16:36
  • @adrian `b` is contiguous within a given structure, but it's not "within" the structure itself. In other words, the data stored in `b` is not next to `a` in memory. So an array of the structures is contiguous, but it would look like: [a, pointer_to_b; a, pointer_to_b; a, pointer_to_b;] in memory. So the `b` variable is not contiguous with the structure array, which MPI requires. – tpg2114 Mar 26 '12 at 16:39
  • @tpg2114 ah I see what you mean, I thought you meant that the array is split (fragmented) – Adrian Mar 26 '12 at 17:01
  • @tpg2114: this is incorrect. A struct with a variable-size array like Akrerone is trying to use is a perfectly valid and common C idiom: http://stackoverflow.com/q/246977/163956 – Greg Inozemtsev Mar 27 '12 at 03:51

1 Answers1

0

You have the right idea. The code you have written allocates space for one struct with a variable-size array using a C99 style flexible member. The same trick would work with a C90-style zero-length array or 1-sized array.

The struct commonly includes a member to specify the size of the variable-length portion, though that is obviously not a requirement. But you can see how this is a problem for making an array of these structs.

Generally

structure_t my_array[5];
...
my_array[2].a = 0.0;

is the same as

(structure_t*)((void*)my_array + 2*sizeof(structure_t))->a = 0.0;

But what's the sizeof our dynamic struct? Whatever it happens to evaluate to, it is clearly what we want, since it does not include the variable portion.

So we can allocate the array of these structs by doing

void *result = malloc(arraysize * dimstruct);

and it will be contiguous. But we can't use array indexing syntax, since the size of the struct is undefined. Instead we index manually, as hinted above:

structure_t *p = result + i * dimstruct;
p->a = 0.0;

Note that result is a void *. If we declared it as structure_t * the offset calculation would be wrong since it would use multiples of sizeof(structure_t)

Community
  • 1
  • 1
Greg Inozemtsev
  • 4,516
  • 23
  • 26