4

私は構造を持っています

typedef struct foo {
    int lengthOfArray1;
    int lengthOfArray2;
    int* array1;
    int* array2;
} foo;

構造全体とその配列の内容に十分なメモリを割り当てる必要があります。したがって、各配列の長さが5であると仮定します。

foo* bar = (foo*)malloc(sizeof(foo) + (sizeof(int) * 5) + (sizeof(int) * 5));

ここで、array1とarray2を、割り当てられたバッファー内の正しい場所にポイントする必要があります。

bar->array1 = (int*)(&bar->lengthOfArray2 + sizeof(int));
bar->array2 = (int*)(bar->array1 + lengthOfArray2);

これは正しいです?

編集#1

混乱を解消するために、メモリを3つではなく、1つのブロックに保持しようとしています。

編集#2

MSVC 2010コンパイラがC99をサポートしていないため、C99を使用できません(http://stackoverflow.com/questions/6688895/does-microsoft-visual-studio-2010-supports-c99)。

4

3 に答える 3

4

構造体のサイズを割り当てる必要があります。次に、int の配列をそれぞれのサイズで割り当てる必要があります。

foo* bar = malloc(sizeof(foo));

/* somewhere in here the array lengths are set then... */

bar->array1 = malloc(sizeof(int) * bar->lengthOfArray1);
bar->array2 = malloc(sizeof(int) * bar->lengthOfArray2);
于 2012-10-14T05:04:48.343 に答える
3

OPのアプローチに従うと、これでうまくいくはずです。

/* Defining these types allows to change the types without having the need to modify the code. */
typedef int Foo_ArrayElement1_t;
typedef int Foo_ArrayElement2_t;

typedef struct Foo_s {
    size_t lengthOfArray1; /* 'size_t' is the type of choice for array/memory dimensions. */
    size_t lengthOfArray2;
    Foo_ArrayElement1_t * array1;
    Foo_ArrayElement2_t * array2;
} Foo_t;

/*
 * Allocates memory to hold a structure of type Foo_t including size for 
 * 's1' elements referenced by 'array1' and 's2' elements by 'array2'.
 * The arrays' elements are set to 0.
 *
 * Returns a pointer to the freshly allocated memory or NULL if the memory could not 
 * be allocated.
 */
Foo_t * Foo_CreateAndInit(size_t s1, size_t s2)
{
  /* At once allocate all 'Foo_t' (including the memory Foo_t's array pointers shall point to). */
  Foo_t * pfoo = calloc(1,
      sizeof(*pfoo) +
      s1 * sizeof(*(pfoo->array1) + 
      s2 * sizeof(*(pfoo->array2)));
  if (pfoo)
  {
    pfoo->lengthOfArray1 = s1;
    pfoo->lengthOfArray2 = s2;

    /* The first array starts right after foo. */
    pfoo->array1 = (Foo_ArrayElement1_t *) (pfoo + 1); 

    /* The second array starts right after s1 elements of where the first array starts. */
    pfoo->array2 = (Foo_ArrayElement2_t *) (pfoo->array1 + s1); /* That casting here is not 
        necessaryas long as 'Foo_t.array1' and 'Foo_t.array2' point to the same type but makes 
        the code work even if those types were changed to be different. */
  }

  return pfoo;
}

...

Foo_t * foo = Foo_CreateAndInit(5, 5);
于 2012-10-14T15:12:17.497 に答える
1

メモリを少し追加した場合 (C99 のみ):

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

typedef struct foo {
    int lengthOfArray1;
    int lengthOfArray2;
    int *array1;
    int *array2;
    int array[];
} foo;

int main(void)
{
    foo *bar = malloc(sizeof(foo) + (sizeof(int) * 10));

    bar->array1 = &bar->array[0];
    bar->array2 = &bar->array[5]; /* 5 or lengthOfArray1 */

    return 0;
}
于 2012-10-14T07:38:43.417 に答える