2011-10-14 3 views
-1

free()을 사용하여 malloc()을 통해 할당 된 메모리를 해제하려고했습니다.C에서의 free() 함수가 작동하지 않습니다.

구조체 중 일부는 해제되지만 일부는 그대로두고 자녀와 연결되어 있습니다. 또한 루트 (gRootPtr)을 이진 트리로 해제하지 않습니다.

Xcode를 사용하여 이진 트리에서 사용하는 메모리가 해제되었는지 확인하고 if 문도 사용합니다. 내가 메모리를 무료로 사용하고

코드 : I 메모리가 해제되어 있는지 확인하기 위해 사용하고

void FreeMemory(InfoDefiner *InfoCarrier) 
{ 
    if ((*InfoCarrier) != NULL) { 
     FreeMemory((&(*InfoCarrier)->left)); 
     FreeMemory((&(*InfoCarrier)->right)); 
     free((*InfoCarrier)); 
    } 
} 

코드입니다. 이 변수가 해제되지 않을 경우 체크 확인

if (gRootPtr != NULL) { 
    return 1; 
} 
else{ 
    return 0; 
} 
+11

* 기능 C에서 무료()가 작동하지 않습니다. * - 예, 가능합니다. –

+1

if ((* InfoCarrier)! = NULL)'포인터가 NULL이 아닌'InfoDefiner'가 NULL인지 비교합니다. –

+0

일반적으로 표준 라이브러리 함수 (특히 ** free ** 같은 코딩에 필수적인 함수)가 "작동하지 않는"경우 잘못된 것을 수행한다고 가정 할 수 있습니다. –

답변

16

첫째, 포인터 자체를 변경하지 않습니다 무료.

포인터를 NULL로 되돌리려면이 작업을 직접 수행해야합니다.

둘째, 메모리에 어떤 일이 발생하는지에 대해 더 guarentees이 확보 한 후 포인터가 가리키는없는이 있습니다 : 이것은 당신이 실제로free() 경우 작동을 테스트 할 수 없습니다 것을 의미

int *x = malloc(sizeof(int)); 
*x = 42; 
free(x); 
// The vlaue of *x is undefined; it may be 42, it may be 0, 
// it may crash if you touch it, it may do something even worse! 

참고. 엄밀히 말하자면, 아무 것도하지 않아도 free()을 구현하는 것은 합법적입니다 (물론 이것이 사실이라면 결국 메모리 부족 현상이 발생합니다).

5

. free(pointer)은 해당 포인터를 NULL로 설정하지 않습니다. 당신이 그런 경우가 될하려는 경우, 당신은 스스로를 설정해야하고, 그것은 C의 일반적인 관용구이다

free(pointer); 
pointer = NULL; 

이미 그 포인터를 해제한다는 신호를.

2

Calling free does not set the pointer to NULL. 너 스스로 그렇게해야 해.

7.21: Why isn't a pointer null after calling free()? 
    How unsafe is it to use (assign, compare) a pointer value after 
    it's been freed? 

A: When you call free(), the memory pointed to by the passed 
    pointer is freed, but the value of the pointer in the caller 
    probably remains unchanged, because C's pass-by-value semantics 
    mean that called functions never permanently change the values 
    of their arguments. (See also question 4.8.) 

    A pointer value which has been freed is, strictly speaking, 
    invalid, and *any* use of it, even if it is not dereferenced, 
    can theoretically lead to trouble, though as a quality of 
    implementation issue, most implementations will probably not go 
    out of their way to generate exceptions for innocuous uses of 
    invalid pointers. 

    References: ISO Sec. 7.10.3; Rationale Sec. 3.2.2.3.
1

함수 free은 할당 된 메모리에 대한 포인터를 사용하지만 실제로는 그렇게 할 수있는 방법이 없습니다 (포인터를 가져와야 할 것입니다). 이 시나리오에서

일반적인 사용 사례는 다음과 같습니다 포인터 당신이 할당 된 힙에 역 참조를하지 않는 주면

free(myptr); 
myptr = NULL; 
2

free()이 실패 할 유일한 이유입니다. 이 동작은 명확하게 정의되어 있으며 free()이 작동하거나 프로그램이 액세스 위반으로 인해 중지됩니다.

포인터를 해제 한 후에 포인터를 다시 초기화하는 것이 좋습니다.이것은 다음을 수행 할 수 있습니다

  • 당신이 이미 할당 된 포인터 (따라서 원래의 블록에 대한 참조를 잃고 누출의 원인) (realloc을()에도 불구하고)의 상부에 할당하지 않도록합니다.

  • 당신은 포인터 (또는 NULL) 초기화되는 경우

이 모두 볼 테스트에 의해 용이하게 할당되지 않았다 여유 최근 해제 된 메모리 또는 메모리를 수행해야합니다.

이 작업은 수동으로 수행하는 것이 가장 바람직합니다.

void safe_free(void **p) 
{      
     if (*p != NULL) { 
       free(*p); 
       *p = NULL; 
     }     
} 

하십시오 돈 : 나는 할당되지도 시도 메모리를 해제 피할이 작은 보석처럼 자동으로 재 구현 free() 그래서 그 포인터를 다시 초기화의 일부 매우 복잡한 방법을 보았다 ' 그 코드를 사용하면 형식이 틀린 포인터를 역 참조하기 때문에 엄격한 플랫폼에서 끔찍하게 깨질 것입니다. 또한 포인터가 문자열 리터럴 인 경우 어떻게해야합니까?

대신 포인터를 추적하고 해제 한 후 초기화하십시오.

관련 문제