2017-12-09 19 views
2

내가 arraymalloc()를 사용하여 할당 된 pointers을 저장할 free()를 할 수 없습니다 이후 그 다음 free 모든. 그러나 프로그램이 불평하지 않더라도 작동하지 않습니다. cleanMemManager() 아래 실제로 freemain() 내부에서 테스트했을 때 메모리는 이 아니며 이 아니며 ???을 인쇄합니다.C - 배열에서의 malloc()와 저장 포인터, 그들이 나중에

코드 :이 사용하는 구문을 이해하지 못하는

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

void **ptrList = NULL; 

void tfree(void** ptr) 
{ 
    free(*ptr); 
    *ptr = NULL; 
} 

void* talloc(int size) 
{ 
    void* ptr = malloc(size); 
    ptrList[0] = ptr; ///No clue if this actually does what I think it does 
    return ptrList[0]; 
} 

void initMemManager() 
{ 
    ptrList = (void**)malloc(sizeof(void**) * 3); 
    memset(ptrList, 0, sizeof(void**) * 3); 
} 

void cleanMemManager() 
{ 
    tfree(&ptrList[0]); //Doesn't free the right pointer it seems 
} 

int main() 
{ 
    initMemManager(); 
    char* ptr = (char*)talloc(3); 
    cleanMemManager(); 

    if (ptr != NULL) //This will trigger and I'm not expecting it to 
     printf("???"); 

    getchar(); 
    return 0; 
} 

는 포인터가 실제로 전혀 감동되지 않습니다? 어떤 오류도 발생시키지 않으므로 그때부터 무엇이 자유 롭습니까?

+0

:'void * ptr = malloc (size);'1) 작업이 성공적으로 수행되었는지 확인하기 위해 반환 값을 항상 확인 (! = NULL)합니다. 2)'malloc()'함수는'int_type'가 아닌'size_t' 타입의 매개 변수를 기대합니다. (이 암시 적 변환은'size_t'가 부호가 없으며'int'가 서명되었으므로 실패 할 수 있습니다.) – user3629249

답변

5

main에서 char *ptr = (char*)talloc(3);은 로컬 변수로 선언합니다. 여기에는 talloc에 의해 반환 된 값의 복사본이 들어 있으며 서브 루틴 중 어느 것도 ptr 또는 그 위치를 알 수 없습니다. 따라서 어느 누구도 ptr의 값을 변경하지 않습니다. 따라서 if (ptr != NULL)에 도달하면 ptr의 값은 변경되지 않습니다. 또한

: 당신이 sizeof(void**)이 경우

  • initMemManager에서, 당신은 두 곳에서 sizeof(void *)을 사용해야합니다. 이 장소에서는 개체가 아닌 void * 개체를 할당하고 복사합니다.

  • 해제 될 때 NULL에 자동으로 포인터를 설정하는 스마트 메모리 관리자를 구현하는 것처럼 보입니다. C에서 그렇게하려면 포인터 사본을 포기해야합니다. 예를 들어, ptrptrList[0]의 사본이지만 tfreeNULL으로 전달되는 사본 만 설정합니다. 우리는 그러한 시스템을 구축하는 데 조언을 줄 수 있지만, 번거로워 질 것입니다. 즉, 메모리 관리자가 포인터와 그 복사본 (및 포인터 연산을 통해 포인터를 파생시킨 데이터베이스)을 유지해야합니다. 또는 그 ptrList 배열을 통해 간접적으로 모든 것을 참조해야합니다.이 배열은 소스 코드에 혼란을줍니다. 불행하게도, C는 이것을위한 좋은 언어가 아닙니다.

+0

그래, sizeof (void *) 것은 나쁘다. 나는 트리플 포인터로 장난을 치고 돌아 왔다는 것을 잊어 버렸다. 나머지 정보를 가져 주셔서 감사합니다. – nurtul

3

Freeing은 할당 된 블록을 가리키는 포인터가 NULL로 설정된다는 것을 보장하지 않습니다. 당신이 실제로

if (ptrList[0] != NULL) 
     printf("ptrList[0] != NULL"); 

을 수행하려고하면 당신은 출력 것이다, 프로그램은 출력하지하고 cleanMemManager() 함수 호출을 제거하면 것을 볼 수 있습니다. 즉, tfree 함수가 의도 한대로 작동하고 할당 된 메모리가 해제됩니다.

변수가 NULL로 설정되지 않은 이유는 ptr이 여전히 이전 주소를 저장하고 있기 때문입니다. cleanMemManager()에는 변수 ptr을 돌연변이시킬 방법이 없습니다. 이것은 일반적으로 매달린 포인터 또는 무료 후에 사용이라고합니다.

또한 free()은 할당 된 공간을 클린/제로 아웃하지 않습니다. 블록은 단순히 "사용 가능"으로 표시됩니다. 빈 블록이 다른 malloc 요청으로 덮어 쓰기 될 때까지 데이터는 잠시 동안 메모리에 남아 있습니다.

+0

감사합니다. – nurtul