2012-04-09 2 views
1

또 다른 C 질문 : C 구조체의 메모리 관리

이의 내가 char* 타입의 포인터 멤버가 구조체가 있다고 가정 해 보자. 내가 구조체의 인스턴스를 초기화 할 때

나는 malloc 전화 : 다음

MyStruct* ptr = (MyStruct*)malloc(sizeof(MyStruct) 

그리고를 char* 회원 메모리의 256 바이트를 할당 :

ptr->mem = (char*)malloc(sizeof(char)*256); 

포인터 멤버에 무슨 전화 할 때 가리키는 메모리가 free(ptr);입니까? valgrind를 사용하여 프로그램을 검사 할 때 메모리 누수가 있음을 알았지 만 명시 적으로 호출 할 때 free(ptr->member); 여전히 메모리 누수가 있고 valgrind에 "유효하지 않은"오류가 표시됩니다.

메모리를 관리하는 적절한 방법은 무엇입니까? 회원이 지적 했습니까?

+1

C에서'malloc'의 반환 값을 변환해서는 안됩니다. –

+0

'memcpy '의 문제점은 무엇입니까? –

+0

@Oli Charlesworth : 왜 안 되니? –

답변

2

어림짐작은 malloc에 대한 모든 (성공한) 호출에 대해 하나의 free이 필요하다는 것입니다 (일반적으로 역순으로 발생 함).

free(ptr) 만있는 경우 ptr->mem에 할당 된 메모리에 액세스 할 수있는 방법이 없으므로 메모리 누수가 발생합니다. free(ptr->mem) 만있는 경우 완전히 지워지지 않았습니다 (메모리 누수만큼 나쁘지는 않음).

3

당신은 즉시 당신이 free(ptr), ptr의 구성원 중 누구도 더 이상 유효하지 않습니다 전화로 다음 구조체, 첫번째> 회원 ptr-을 무료로

free(ptr->member); 
free(ptr); 
3

있습니다. 당신은 그들과 아무 것도 할 수 없습니다. 그러나 ptr->mem 인 것으로 지적 된 메모리는 여전히 해제되어야합니다. 따라서 먼저 free(ptr->mem) 중 하나를 사용해야하며, 그렇지 않으면 해당 포인터를 어딘가에 복사해야 유효한 포인터를 확보해야합니다.

화합물 구조를 할당하고 해제의 일반적인 패턴은 같은 것입니다 (그리고 이렇게 좋은 깨끗한 기능에서 그들을 마무리하는 것이 도움이된다) : 회원의 일부는 복잡한 구조체 자체가 경우

MyStruct* MakeMyStruct() { 
    MyStruct* ptr = malloc(sizeof(MyStruct)); //N.B. don't need cast if it's C 
    ptr->mem = malloc(sizeof(char)*256); 
    //initialise other members 
    return ptr; 
} 

void DestroyMyStruct(MyStruct *ptr) { 
    //Free members first, then the struct 
    free(ptr->mem); 
    free(ptr); 
} 

을 위의 두 함수에서 mallocfree 대신 MakeWhateverDestroyWhatever으로 할당/해제됩니다.

+0

+1 좋은 깨끗한 기능. 'DestroyMyStruct'에'ptr-> mem = NULL; '을 추가하면 버그를 다른 곳에서 잡는 데 도움이 될 것이라고 주장 할 수 있습니다. –

+0

+1. 추상화는 당신의 친구입니다. –

+0

그게 내가 구현 한거야,하지만 난 몇 가지 이유에 대한 이중 자유 오류가 .. valgrind 출력 더블 자유가 구조체를 파괴하는 방법에서 보여줍니다 .. – Bob