2016-05-14 6 views
0

は動的にネストされた階層内の「内部」構造体を割り当てることがことが望ましいですか?親構造体が動的に割り当てられている場合でも、それは重要ですか?なぜ/どのように重要ですか?異なる、一見矛盾する、メモリの意味が私が扱っているコードベースで扱われる方法の意味を理解しようとしています。優先配分

struct Foo_type { 
    int i; 
}; typedef struct Foo_type Foo; 

struct Bar_type { 
    Foo* f; 
}; typedef struct Bar_type Bar; 

int main() { 
    Bar* b = malloc(sizeof(Bar)); 
    b->f = malloc(sizeof(Foo)); 

    /* yada yada yada */ 

    free(b->f); 
    free(b); 
    return 0; 
} 

は、彼らが異なる/等価です:とは対照的に

struct Foo_type { 
    int i; 
}; typedef struct Foo_type Foo; 

struct Bar_type { 
    Foo f; 
}; typedef struct Bar_type Bar; 

int main() { 
    Bar* b = malloc(sizeof(Bar)); 

    /* yada yada yada */ 

    free(b); 
    return 0; 
} 

:たとえば

のメリットは何ですか?

+2

(1)単純です。 (2)はより柔軟である。あなたが本当に必要でない限り(1)を好む(2)。 – Matt

+0

@Matt Ahhは理にかなっています。だから、はるかに明確な事実の後には:)基本的には2で行く、その後のfooのサイズがわからない場合は...本当に、原則として、すべてのあなたが得るということでしょうか? –

+0

はい、正しいと思います。 – Matt

答えて

0

場合1には、構造体は、一つのメモリアロケーションブロックに含まれているので、あなたはそれをmemcpyをし、それを解放するための唯一の自由を必要とすることができます。あなたがお互いの横に必ずしも2つのメモリブロックを占有する場合には2

ので、あなたはそれらの二つのブロックを追跡する追加の手間を持つことになります。

あなたがBar_typeで複数のポインタとメンバーを持ち始める場合は、型のインスタンスをコピーするの複雑さを増加します。 @AndersKに添加して

+0

素晴らしいアイデアですが、それは再帰的な構造体でない限り動作します。 – cup

1

。答え、第1の方法は(非動的)基部として導出我々は継承をエミュレートする場合由来struct内部ベースstructを宣言好ましく、鋳造される:

#include <stdio.h> 
#include <stdlib.h> 

struct foo { 
    int i; 
}; 

struct bar { 
    struct foo f; 
}; 

static void func(struct foo *f, int i) 
{ 
    f->i = i; 
} 

int main(void) 
{ 
    struct bar *b = malloc(sizeof(*b)); 

    func((struct foo *)b, 1); 
    printf("%d\n", b->f.i); 
    return 0; 
}