2012-12-14 108 views
0

使用嵌套结构时,我倾向于执行类似下面的操作。我想知道这是否是在这种特殊情况下初始化structs的正确方法,或者是否有更好的方法。在C中初始化嵌套结构的正确方法

#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(); 
    } 
} 
+1

为什么在memset之后将0赋给变量? – imreal

+0

@尼克:这正是我不确定的部分。显然不需要。 –

+0

这是不需要的:更大的问题是你分配了一堆'外部',然后分配一堆'内部',但将它们分配给第一个'外部'。 – imreal

回答

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; 
} 

试试这个...我希望这有助于...

+0

所以基本上'memset'会将结构字段初始化为'0'而不管它们的类型是否正确? –

+1

memset只是想要的指针和大小,而不是类型.... –

+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); 
    ... 
} 
+0

这是一个不错的方法太。谢谢! –

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 
} 

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