2012-09-02 4 views
0

나는이 구조체를 가지고 :어떻게 구조체 자체에 대한 메모리를 할당하고, 회원은

struct foo { 
    char *a; 
    char *b; 
    char *c; 
    char *d; 
}; 

대신 등의 구조체에 대한 자체 회원을 공간을 할당 할 수있어,이 같은

struct foo f; 
f.a = malloc(); 
f.b = malloc(); 
f.c = malloc(); 
f.d = malloc(); 
strcpy(f.a, "a"); 
strcpy(f.b, "b"); 
//.. 

뭔가 (그게 작동하지 않는 녀석) :

struct foo f = malloc(sizeof(struct f)); 
strpcy(f.a, "a"); 
//etc 
+0

무엇이 질문입니까? –

+0

수정 된 제목. :) – Jack

답변

1

이것을 생성자라고합니다. 오류 처리를 생략하면 다음과 같이 보일 수 있습니다.

struct foo *new_foo() 
{ 
    struct foo *obj = malloc(sizeof(struct foo)); 
    obj->a = malloc(...); 
    obj->b = malloc(...); 
    obj->x = new_x(...); 
    ... 
    return obj; 
} 

및 해당 소멸자가 필요합니다. 이와 같은 코드를 자주 작성해야하는 경우 C++로 전환해야 할 때가 있습니다. :).

+0

아주 좋습니다. 나는 그것을 잊어 버렸다. 감사! 하지만이 구현의 설계자는 NULL이 아닌 값을 어떻게 확인합니까? 누가 그것을 확인해야합니까, 생성자 또는 호출자입니까? 각'malloc()'/'calloc()'호출 후에 반환 값이 null이 아닌 값을 가지지 만 NULL인지 아닌지 확인하면 이전에 할당 된 멤버 또는 호출자를 무료로 할 수 있습니까? – Jack

+0

C++이 아직 없습니다. 나는 C++ 팬이 아니다. 하지만 어쨌든 고마워요 :) – Jack

+0

C++은 예외 ('bad_alloc')와 RAII를 사용합니다. 드문 경우이지만 메모리 할당 실패는 어쨌든 종종 복구 할 수 없습니다. C 코드에 관해서는 아마 생성자와 함께'free()'(또는 아마도 quit 또는 two :) 체크를 할 것입니다. 이 함수는 단순히 발신자의 삶을 편하게하기 위해 존재합니다. 오류 복구로 그들을 부담시키는 것은 전체적인 관점에 위배됩니다. – aib

1

c에서 모든 "동적"가변 크기를 알고 있다면 할 수 있습니다. 건설 시간.

끝에 물론
struct foo *f = malloc(sizeof(struct f) + nSizeExtra); 

f->a = (char*) (f + 1); 
f->b = ((char*) (f + 1)) + nLengthOfA; 
f->c = ((char*) (f + 1)) + nLengthOfA + nLengthOfB; 
f->d = ((char*) (f + 1)) + nLengthOfA + nLengthOfB + nLengthOfC; 

f (안 회원) 당신이 당신의 구조체와 그것의 구성원에 대한 메모리를 할당 할 수 있습니다 물론

1

을 확보해야하지만 당신은 모든 일에 대해 하나의 연속 된 메모리를 할당하는 경우 어쨌든 구조체 멤버를 초기화해야하므로 원하는만큼 쉽게 할 수 없습니다.

+0

왜 안 되니? 내가 모르는 특별한 이유가 있니? – valdo

+0

자, 방금 위에서 쓴 것은 정확하지 않지만 실제로 malloc을 한 번 사용하고 구조체를 사용하고 멤버가 올바르게 초기화되었으므로 Jack의 대답에 실제로 응답한다고 생각합니다. 다른 사람들이 제안한 것을 수행하면 어쨌든 멤버를 초기화해야합니다. – piokuc

+0

내 대답을 편집했습니다. – piokuc

3

구조체 자체와 해당 멤버의 메모리를 한 번에 할당 할 수 있습니다. 얼마나 많은 양을 필요로하는지 (전체적으로) 알아야하고 가능한 모든 정렬 문제를 처리해야합니다 (이 특별한 경우에는 존재하지 않음).

struct foo *f = malloc(sizeof *f + size_a + size_b + size_c + size_d); 
f.a = (char*)(f + 1); 
// ... 
관련 문제