2014-12-18 3 views
0

C에서 포인터를 올바르게 사용하는 방법을 배우려고합니다. 현재 값 앞에 값이있는 노드를 삽입하는 함수를 작성하려고합니다. 내 기능은 다음과 같습니다.주어진 요소 앞에 이중 링크 된 목록 삽입

struct list *listAddBefore(struct list *element, int insertWhat, int insertBefore) 
{ 
    element = listToFirst(element); 

    while (element -> next) 
    { 
     if (element -> value == insertBefore) 
     { 
      struct list *temp = listCreateElement(insertWhat, element->prev, element); 

      element -> prev -> next = temp; 
      element -> prev = temp; 

      return temp; 
     } 
     element = element -> next; 
    } 

    return NULL; 
} 
struct list *listToFirst(struct list *element) 
{ 
    while (element -> prev) 
     element = element -> prev; 

    return element; 
} 


struct list *listCreateElement(int value, struct list *prev, struct list *next) 
{ 
    struct list *element = (struct list *) malloc(sizeof(struct list)); 

element -> value = value; 
element -> prev = prev; 
element -> next = next; 
return element; 
} 

무엇이 문제입니까? 컴파일러가 나에게 세그먼트 화 오류를 준다.

+1

실행을 작동하는 방법을 배울 수 있도록 코드를 수정했습니다. 그것은 그것이 어디에서 세분되는지 알려줄 것입니다. –

+1

...'struct list'의 정의를 보여줍니다. –

+1

:'element-> prev -> next = temp;','element-> prev'는'element'가 목록에 처음 있다면 null 일 수 있습니다. – agbinfo

답변

1
  1. 코드는 즉시 NULL를 반환합니다 첫 번째 요소 element->next = NULL 따라서 함수에 대한 이후

    while (element) 
    

    을해야 하나 중요한 문제

    while (element->next) 
    

    있습니다. 그런 다음 head 요소를 다시 전달하고이 함수를 호출 할 때마다이 동작을 반복합니다. 이 유효한지 여부를 element->prev 역 참조 첫 번째 노드에 대한 NULL해야합니다 여기

    element->prev->next = temp; 
    

  2. , 당신은 그렇지 않으면 당신은 segmentation fault의 원인이됩니다 확인해야합니다. 이것은 노드를 연결하는 올바른 방법입니다.

는 당신이 연결리스트 디버거와

struct list *listToFirst(struct list *element) 
{ 
    if (element == NULL) /* check before dereferencing */ 
     return NULL; 
    while (element->previous != NULL) 
     element = element->previous; 
    return element; 
} 


struct list *listCreateElement(int value, struct list *prev, struct list *next) 
{ 
    struct list *element = (struct list *)malloc(sizeof(struct list)); 
    if (element == NULL) /* check the return value of malloc before dereference */ 
     return NULL; 
    element->value = value; 
    element->previous = prev; 
    element->next = next; 
    /* 
    * here we test if there is a previous node, if there is one 
    * we relink the node to point to element as it's next node. 
    */ 
    if (prev != NULL) 
     prev->next = element; 
    return element; 
} 

struct list *listAddBefore(struct list *element, int insertWhat, int insertBefore) 
{ 
    element = listToFirst(element); 
    while (element != NULL) /* here is the most important fix */ 
    { 
     if (element->value == insertBefore) 
      return listCreateElement(insertWhat, element->previous, element); 
     /* 
     * Since the listCreateElement function takes care of linking the nodes 
     * this is all we have to do here. 
     * 
     * note: Doing the linking in the listCreateElement, makes it more clear. 
     */ 

     element = element->next; 
    } 
    return NULL; 
} 

/* you should also add a free function, since you allocated the structs using malloc */ 
void freeList(struct list *list) 
{ 
    struct list *current; 

    current = list; 
    while (current != NULL) 
    { 
     struct list *next; 

     next = current->next; 
     free(current); 
     current = next; 
    } 
} 

int main(int argc, char **argv) 
{ 
    struct list *element; 

    element = listCreateElement(0, NULL, NULL); 
    element = listAddBefore(element, 1, 0); 
    element = listAddBefore(element, 2, 1); 
    element = listAddBefore(element, 3, 2); 

    /* do something with the list */ 

    /* free the allocated memory */ 
    freeList(element); 
    return 0; 
}