2013-04-23 3 views
0

여기 팝 내 코드입니다 :팝 기능에서 공간을 비우거나 할당 해제 할 수 없습니까?

int pop (struct_of_ints *head_node){ 
int val; 
if (head_node == NULL){ 
    fprintf(stderr, "Empty stack.\n"); 
    return -1; 
} 
else { 
    struct_of_ints *curr; 
    struct_of_ints *prev; 
    curr = head_node; 
    prev = NULL; 

     while (curr->next != NULL) { 
      prev = curr; 
      curr = curr->next; 
     } 

     val = curr->value; 

     if (prev == NULL) 
      head_node = NULL; 
    else 
      prev->next = curr->next; 
     free(curr) 
     return val; 


} 

} 

내가 (CURR)를 확보하려고하지만, 나는 세그먼트 오류를 ​​얻을 내가 Valgrind의 실행할 때 나는 (잘못된 자유 "와 같은 메시지를 얻을 수)/삭제/삭제 [] ","주소 0x51c1f60은 크기 32의 블록 안의 16 바이트이고 크기 8의 "유효하지 않은 읽기"입니다 ... 무엇이 잘못되었는지는 알지 못합니다. 누구든지 도와 주시면 감사하겠습니다. 감사!

+0

대신 꼬리 포인터를 사용하여 이중 연결 목록을 사용하는 것이 좋습니다. 꼬리에서 제거하고 싶다면 삶이 더 쉬워 질 것입니다. 또는 스택을 구현하는 경우 머리 대신/pop을 누르십시오. –

+0

'-g' 플래그로 코드를 컴파일하고'gdb'를 실행하여 에러를 확인하십시오. – MYMNeo

답변

3

값으로 전달되는 함수에서 포인터 * head_node를 전달 중입니다. *의 head_node를 업데이트하려면 ** head_node를 통과 시도하고 ::

으로 코드를 변경
int pop (struct_of_ints **head_node) 
{ 
    int val; 
    if (*head_node == NULL) 
    { 
     fprintf(stderr, "Empty stack.\n"); 
     return -1; 
    } 
    else 
    { 
     struct_of_ints *curr; 
     struct_of_ints *prev; 
     curr = *head_node; 
     prev = NULL; 
     while (curr->next != NULL) 
     { 
      prev = curr; 
      curr = curr->next; 
     } 

     val = curr->value; 

     if (prev == NULL) 
      *head_node = NULL; 
     else 
      prev->next = curr->next; 
     free(curr) 
     return val; 
    } 
} 
2

내 생각이 당신이 모든 노드를 펑 후에 만 ​​발생한다는 것입니다, 다음 한 번 더 팝하려고합니다. 이는 함수 안에있는 head_node에 대한 할당이 함수를 호출 한 코드로 전파되지 않기 때문입니다. head_node은 함수 내부의 로컬 변수이므로 참조 (포인터에 대한 포인터)로 전달해야합니다.

마지막 노드가 팝되면 어떤 일이 발생합니까?이 함수는 자유이지만 그 코드를 호출하는 코드는 여전히 포인터를 갖습니다. 따라서 다음 호출은 free'd 메모리에 대한 포인터와 함께있을 것입니다. 포인터가 액세스 될 때 동작이 정의되지 않았습니다. 정의되지 않은 동작으로 인해 충돌이 자주 발생합니다.

관련 문제