0

ネストされた構造を使用するとき、私は次のようなことをする傾向があります。structsこの特定のケースでそれが初期化する適切な方法であるかどうか、またはそれを行うためのより良い方法があるかどうかを知りたいです。

#include <string.h>
#include <stdlib.h>

typedef struct inner_struct { 
   char *name;
   int account;
} inner;

typedef struct outer_struct {
   int count;
   char *company; 
   inner *my_inner;
} outer;

outer *
initialize_outer (size_t max) {
   outer *out = malloc(sizeof (outer) * max);
   if (out) {
      memset(out, 0, sizeof *out * max);
      out->count = 0;
      out->company = NULL; 
   }   
   return out;
}

inner *
initialize_inner () {
   inner *in = malloc(sizeof (inner));
   if (in) {
      memset(in, 0, sizeof *in);
      in->account = 0;
      in->name = NULL; 
   }   
   return in; 
}

int main(int argc, char *argv[]){
   int i;
   size_t max_out = 20;
   outer *my_out = initialize_outer(max_out);
   for (i = 0; i<max_out;i++) {
      my_out[i].my_inner = initialize_inner();
   }
}
4

3 に答える 3

4

使ってみませんかcalloc()

outer *
initialize_outer (size_t max) {
    return calloc(max, sizeof(outer));
}

inner *
initialize_inner (size_t max) {
    return calloc(max, sizeof(inner));
}

ただし、簡単にするためにこれを行うと思います。

typedef struct outer_struct {
    int count;
    char *company; 
    inner my_inner[];
} outer;

outer *
initialize (size_t max_out, size_t max_in) {
    return calloc(1, (sizeof (outer) + sizeof (inner) * max_in) * max_out);
}

int main(int argc, char *argv[]){
    size_t max_out = 20, max_in = 10; 
    outer *my_out = initialize(max_out, max_in);
    ...
}
于 2012-12-14T05:27:43.633 に答える
1

ゼロへの余分な割り当ては別として、initialize_outerからinitialize_innerを呼び出す必要があります。これは、「outer」が「inner」なしで目的を満たしているようには見えないためです。

これにより、別の問題が発生します。プライベートカプセル化を使用した、適切なオブジェクト指向プログラム設計の使用を検討する必要があります。

inner.h

typedef struct inner_struct;


inner* inner_init (void);
void   inner_free (inner* in); // you need a cleanup function!

// an example of a "setter" function:
void init_set_name (inner* in, const char* name);  

// similar setter and getter functions needed here

inner.c

#include "inner.h"

typedef struct { 
   char* name;
   int   account;
} inner;

inner* inner_init (void) 
{
   inner* in = calloc(1, sizeof (inner));
   if (in == NULL)
   {
     // error_handling
   }

   return in; 
}

void inner_free (inner* in)
{
  // if in->name was allocated dynamically, free it here

  free(in);
}

void init_set_name (inner* in, const char* name)
{
  // assign name to in->name, possibly malloc memory for it
}

アウター.h

#include "inner.h"

typedef struct outer_struct;


outer* outer_init (void);
void   outer_free (outer* out);

// setter and getter functions needed here

アウター.c

#include "outer.h"

typedef struct 
{
   int count;
   char *company; 
   inner *my_inner;
} outer;


outer* outer_init (void) 
{
   outer* out = calloc(1, sizeof(outer));
   if(out == NULL)
   {
     // error handling
   }

   out->my_inner = inner_init();

   return out;
}

void outer_free (outer* out)
{
  inner_free(out->my_inner);
  free(out);
}

the_application.c

#include "outer.h"

#define MAX_OUT 20

int main(int argc, char *argv[]){

   outer* out_arr [MAX_OUT]

   for(int i=0; i<MAX_OUT; i++)
   {
     out_arr[i] = outer_init();
   }

   ...

   for(int i=0; i<MAX_OUT; i++)
   {
     outer_free(out_arr[i]);
   }
}
于 2012-12-14T07:39:45.820 に答える
1
outer *
initialize_outer (size_t max) {
    outer *out = malloc(sizeof (outer) * max);
    if (out) {
        memset(out, 0, sizeof (outer) * max);
        out->count = 0; // no need assign 0 to 'account' and NULL to 'name' field
        out->company = NULL; // because memset already assigns 0 to it.
    }   
    return out;
}

inner *
initialize_inner (size_t max) {
    inner *in = malloc(sizeof (inner) * max);
    if (in) {
        memset(in, 0, sizeof (inner) * max);
        in->account = 0; // no need assign 0 to 'account' and NULL to 'name' field
        in->name = NULL; // because memset already assigns 0 to it.
    }   
    return in; 
}

これを試してください...これがお役に立てば幸いです...

于 2012-12-14T05:15:36.103 に答える