在C中初始化嵌套结构的正确方法

时间:2012-12-14 04:59:01

标签: c struct initialization memset

使用嵌套结构时,我倾向于执行以下操作。我想知道这是否是在这种特殊情况下初始化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();
   }
}

3 个答案:

答案 0 :(得分: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);
    ...
}

答案 1 :(得分: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; 
}

试试这个...我希望这会有所帮助...

答案 2 :(得分:1)

除了多余的零赋值,你应该从initialize_outer调用initialize_inner,因为如果没有“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
}

outer.h

#include "inner.h"

typedef struct outer_struct;


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

// setter and getter functions needed here

outer.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]);
   }
}