2012-12-14 109 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]); 
    } 
}