【问题标题】:Proper way to initialize nested structs in C在 C 中初始化嵌套结构的正确方法
【发布时间】:2012-12-14 04:59:01
【问题描述】:

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

【问题讨论】:

  • 为什么在memset之后给变量赋值0?
  • @Nick:这正是我不确定的部分。显然不需要。
  • 不需要:更大的问题是你分配了一堆outers,然后分配了一堆inners,但只分配给第一个outer。跨度>
  • 我本来打算做my_out[i].my_inner。感谢您的提醒!

标签: c struct initialization memset


【解决方案1】:

为什么不使用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);
    ...
}

【讨论】:

  • 这也是一个不错的方法。谢谢!
【解决方案2】:
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; 
}

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

【讨论】:

  • 所以基本上memset 会将结构字段初始化为0 而不管它们的类型,对吗?
  • 上述解决方案(代码)是否有用
【解决方案3】:

除了将多余的赋值为零之外,您可能应该从 initialize_outer 调用 initialize_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]);
   }
}

【讨论】:

    猜你喜欢
    • 2011-08-20
    • 1970-01-01
    • 1970-01-01
    • 2019-02-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多