2016-10-06 2 views
0

그래서이 코드를 작성하면 목록을 작성하고 주어진 현재 NODE 이전/이후에 노드를 삽입하는 것처럼 기본 이중 연결 목록 작업을 수행합니다. 주어진 현재 노드를 제거하고, 그런 다음에는 목록을 파괴하려고 할 때이 문제에 부딪혔다. 무슨 일이 일어나는가, 내가 목록을 없애면, 모든 노드를 적절히 할당 해제한다. (적어도 나는 디버거 시계에서 보았던 것으로 생각한다.) 그러나 노드와 꼬리 포인터가 노드가 없기 때문에 NULL을 가리키는지를 체크 할 때 더 이상 존재하지만, 헤드는 NULL을 가리킨다. 그러나 내 꼬리는 여전히 내가 적절하게 할당 해제되지 않은 노드인지 아니면 다른 것이 아닌지 확실하지 않은 무언가를 가리킨다.왜 내 꼬리는 여전히 가리키는 대신 NULL을 가리키는 대신 무언가를 가리키고 있습니다

누군가 무슨 일이 일어 났는지 말해 줄 수 있습니까? 다음은 관련 코드입니다.

따라서 모든 그것을 왜 그 나는 DListDestroy 기능 (상단의 첫 번째)를 사용하여 목록을 파괴 할 때, 그래서 다시 목록
void DListDestruct(DList* list) { 
DListNode* tempHead = list->head;; 

while (tempHead != NULL) { 
    tempHead = tempHead->next; 
    free(list->head); 
    list->head = tempHead; 
} 

if (list->tail == NULL) { 
    list->size = 0; 
} 


} 


    //Creation of the structs for the list  

typedef struct DListNode_struct { 
    char *str; 
    int blankIndex; 
    int blankLength; 
    struct DListNode_struct *next; 
    struct DListNode_struct *prev; 
} DListNode; 

typedef struct DList_struct { 
    int size; 
    DListNode *head; 
    DListNode *tail; 
} DList; 



/* This creates a new list and initializes the head/tail */ 

void DListConstruct(DList* list) { 

    list->head = NULL; 
    list->tail = NULL; 
    list->size = 0; 

} 


/* inserts newNode after the given currNode */ 

void DListInsertAfter(DList* list, DListNode* currNode, DListNode* newNode) { 

DListNode* sucNode = NULL; 

if (list->head == NULL) { 
    list->head = newNode; 
    list->tail = newNode; 
    list->size = list->size++; 
} 

else if (currNode == list->tail) { 
    list->tail->next = newNode; 
    newNode->prev = list->tail; 
    list->tail = newNode; 
    list->size = list->size++; 
} 

else { 
    sucNode = currNode->next; 
    newNode->next = sucNode; 
    newNode->prev = currNode; 
    currNode->next = newNode; 
    sucNode->prev = newNode; 
    list->size = list->size++; 
} 
} 


/* inserts newNode before the given currNode */ 
void DListInsertBefore(DList* list, DListNode* currNode, DListNode* newNode) { 
DListNode* predNode; 


if (list->head == NULL) { 
    list->head = newNode; 
    list->tail = newNode; 
    list->size = list->size++; 
} 

else if (currNode->prev != NULL) { 
    predNode = currNode->prev; 
    newNode->next = currNode; 
    newNode->prev = predNode; 
    currNode->prev = newNode; 
    predNode->next = newNode; 
    list->size = list->size++; 
} 

else if (currNode->prev == NULL) { 
    newNode->next = currNode; 
    currNode->prev = newNode; 
    list->head = newNode; 
    list->size = list->size++; 
} 

} 

을 파괴, 모든 노드 할당을 해제 한 기능입니다 노드가 할당 해제되고, 헤드 포인터가 NULL을 가리키고, 테일 포인터가 여전히 포인터를 가리 킵니까?

미리 감사드립니다.

+0

'list-> size = list-> size ++;'-> 정의되지 않은 동작입니다. 그냥'list-> size ++; '를 사용하십시오. – chux

+0

NULL로 꼬리를 설정하는 것이 당신의 임무가 아닙니까? 'DListDestruct()'에서 그것을 어디에서하고 있습니까? 'if (list-> tail == NULL) 대신 { list-> size = 0; }'필요한 것은'list-> tail = NULL; list-> size = 0;'. –

+0

저는 초보자 인 C로 모든 노드를 올바른 방법으로 해제 한 후에 노드가 이미 해제되었으므로 머리와 꼬리 포인터 모두 NULL을 가리켜 야한다고 생각했습니다. 머리와 꼬리 포인터가 모든 노드를 자유롭게 할 때까지 가리켜 야했던 것이 아닌가요? – einacio

답변

0

꼬리말이 당신이 풀어 낸 노드의 주소를 가리키고 있기 때문에 이것은 이제 약간의 쓰레기를 가리키고 있기 때문입니다.

머리글은 "tempHead"가 가리키는 곳을 가리키고 루프의 끝에서 null을 가리 킵니다. 삽입 프로세스 중에 마지막 노드의 다음에 null을 넣기 때문입니다.

결론적으로 말미는 마지막 노드의 주소 인 쓰레기를 가리 킵니다. 머리글은 마지막 노드의 next를 가리키며 이는 NULL입니다.

+0

알았어. 네가 한 말은 이해가가. 하지만 모든 노드를 해제하고 해제 한 노드의 주소가 아니라면 NULL을 가리키는 내 꼬리가 필요합니다. 그래서 목록을 없애고 모든 노드를 해제 할 때 NULL에 내 꼬리 지점을 가질 수있는 방법이 있습니까? – einacio

+1

모든 노드를 해제 한 후에이 줄을 추가하십시오.'list-> tail = NULL; ' – ViewSource

+0

@einacio tail은 NULL로 설정하면 NULL을 유지하고 그렇지 않으면 NULL을 유지합니다. 그처럼 간단합니다. – immibis

관련 문제