2010-12-09 4 views
1

조금 혼란 스럽습니다.free()를 사용할 때 프로그램이 이상하게 변경됨

나는 기본적으로 매우 간단한 파일 시스템을 쓰고 있어요 :
-reads을 데이터 블록에서 파일
에서 -gets 그 블록에서 해시
- 검색이 해시에 대한 링크 목록
-if는

문제 아무것도

을하지 않는다, 발견 -if
을 추가, 찾을 수 없습니다 (? 아마 누출)
내가 무료로 사용하지 않는 프로그램이 많이 느립니다.

무료로 사용하면 프로그램이 더 빨리 실행되고 128 및 256 블록 크기로 끝나지만 512 (삽입 충돌) 시도하면 충돌이 발생합니다. 나는 비주얼 스튜디오에서 일하고 있는데, 그냥 충돌합니다. 나는 통찰력을 제공하지 않는 "VS의 작동을 멈췄다."라는 메시지를 얻습니다.

무료로 사용할 때와 사용하지 않을 때의 결과가 많이 다릅니다.

도움이 될 것입니다.

좋아, 일부 코드 (약칭 함) :

struct list_el 
{ 
    char* hash; 
    struct list_el* next; 
    struct list_el* prev; 
}; 
typedef struct list_el item; 

item* head, *tail; 

void ins(item* ins) 
{ 
item* iterator = (item*)malloc(sizeof(item)); 
if(iterator == NULL) 
{ 
    printf("out of memory\n"); 
    exit(1); 
} 
else if(head != NULL) 
{ 
    iterator = head; 
    while(iterator != NULL) 
    { 
     if(strcmp(iterator->hash, ins->hash) == 0) 
     { 
      //free(iterator); (problem line) 
      matches++; 
      return; 
     } 
     else if(iterator->next != NULL) 
      iterator = iterator->next; 
     else 
      break; 

    } 
} 

unique_blocks++; 
if(head == NULL) 
{ 
    head = ins; 
    ins->prev = NULL; 

} 

else 
{ 
    tail->next = ins; 
    ins->prev = tail; 
} 

tail = ins; 
ins->next = NULL; 
} 


int main() 
{ 
unsigned char* c = (unsigned char*)malloc(BLOCKSIZE+1); 
if(c == NULL) 
    exit(1); 
FILE* fp = fopen("input2","r"); 
if(fp == NULL) 
    exit(1); 
int i = 0; 

char* answer = (char*)malloc(sizeof(char)*90); 
if(answer == NULL) 
    exit(1); 
item* ins_item; 
char ch; 
do 
{ 
    if(i == BLOCKSIZE) 
    {  
     i = 0; 
     answer = sha1((unsigned char*)c); 
     ins_item = (item*)malloc(sizeof(item)); 
     if(ins_item == NULL) 
      exit(1); 
     ins_item->hash = answer; 
     ins(ins_item); 

    } 
    else 
    { 
     ch = fgetc(fp); 
     bytes_read++; 
     c[i] = ch; 
     i++; 
    } 
}while(ch != EOF); 
fclose(fp); 
return 0; 
} 

답변

6

당신의 ins() 기능에서 당신은 :

  • malloc() 메모리와 iterator을 사용하여 나중에

  • 몇 문을 가리 키도록 iterator = head, 즉 할당 된 메모리 영역에 대한 포인터를 잃어버린 것을 의미합니다. 주요 메모리 그리고 그 이후 몇 문을

  • 을 누설하면 어떻게 /하지가 목록에 여전히 있는 동안 당신은 아마 무료로 원하는 동안 free() 항목이, 반복자가 가리키는 (주석에 따라 다름) malloc()

편집에서 지역 :

가 왜 반복자에 대한 메모리를 할당 할 수 있습니까? 보통리스트 반복자는 코드가 현재 조사하고있는 항목을 가리키는 단순한 포인터입니다.

편집 2 :

충돌은 아마 여전히 목록의 일부 해제 (따라서 anavailable) 메모리를 액세스 프로그램에 의해 발생합니다.

해제 된 메모리가 반드시 시스템에 반환되는 것은 아닙니다. 힙 할당자가 작동하는 방식에 따라 다른 malloc() 호출을 통해 프로그램에 다시 할당 될 수도 있습니다. 프로그램이 다시 액세스하려고하면 예상과 다른 데이터를 가질 수 있습니다.

다른 두 지점 :

  • 는 동일한 범위 내에서 고유 사용자 식별자를 유지합니다.컴파일러를 멈추게하지는 못하지만, 인간의 두뇌를 멈추게 할 것입니다. 예 : ins 매개 변수가있는 ins() 함수가 없어야합니다.

  • Visual Studio에는 (필자가 말한) 디버거가 있습니다. 그것을 사용하는 방법을 배우면 많은을 도울 것입니다. 또한

0

는 왜해야합니까 :이 기능적으로 동일

while(iterator != NULL) 
{ 
    if(strcmp(iterator->hash, ins->hash) == 0) 
    { 
     //free(iterator); (problem line) 
     matches++; 
     return; 
    } 
    else if(iterator->next != NULL) 
     iterator = iterator->next; 
    else 
     break; 

} 

:

while(iterator != NULL) 
{ 
    if(strcmp(iterator->hash, ins->hash) == 0) 
    { 
     //free(iterator); (problem line) 
     matches++; 
     return; 
    } 

    iterator = iterator->next; 
} 

하지만 버전이 더 이상 더 이상 오류를 개발할 가능성이 높습니다.

+0

좋은 점. 감사. – prelic

관련 문제