2014-09-17 3 views
0

이중 연결 목록을 쓰려고합니다. 다음 코드는 테스트를 통과하지만 next 방향과 prev 방향의 새 노드에 메모리를 할당합니다. 특히, 문제는 을 push 함수에 할당 할 필요가 없다고 생각합니다. 그 노드는 이미 과거 반복에서 new으로 할당 되었기 때문입니다. 그러나 을 지정하지 않으면 new->prev = current을 할당하지 않고 current 세그먼트 화 오류가 발생합니다. current을 할당하지 않거나 ->prev을 사용하면 아래 코드가 단일 연결 목록으로 올바르게 작동합니다.C에서 이중 연결 목록의 메모리 문제

현재 malloc을 제거한 후 인쇄 테스트 후에 코드가 세분화됩니다 (첫 번째 사용시 prev).

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

struct list{ 
    int value; 
    struct list *next; 
    struct list *prev; 
}; 
struct list *head; 
struct list *tail; 

void init(int val){ 
    head = (struct list *)malloc(sizeof(struct list *)); 
    head->value = val; 
    head->next = NULL; 
    head->prev = NULL; 

    tail = malloc(sizeof(struct list *)); 
    tail->value = val; 
    tail->next = NULL; 
    tail->prev = NULL; 

} 

void push(int val){ 
    struct list *new; 
    struct list *current; 
    new = (struct list *)malloc(sizeof(struct list *)); //allocate memory space for next side 
    current = (struct list *)malloc(sizeof(struct list *)); //allocate memory space for prev side 
    new->value = val; 
    new->next = NULL; 
    current = head; 
    while(current->next!=NULL){current = current->next;} 
    new->prev = current; 
    current->next = new; 
    tail = new; 
} 

int main(){ 
    printf("init with 10\n"); 
    init(10); 
    printf("pushing 11\n"); 
    push(11); 
    printf("pushing 12\n"); 
    push(12); 
    printf("pushing 13\n"); 
    push(13); 
    printf("testing\n"); 
    printf("2-1 %d\n",head->next->prev->value); 
    printf("3-1 %d\n",head->next->next->prev->value); 
    printf("h4-1 %d\n",head->next->next->next->prev->value); 
    printf("t-1 %d\n",tail->prev->value); 
    printf("t-2 %d\n",tail->prev->prev->value); 
    printf("t %d\n",tail->value); 
} 
+3

왜'init()'이'tail-> prev = NULL; IMO,'꼬리'와'머리'는 같은 가치를 가져야합니다. 'malloc()'을 2 번 호출 할 필요가 없다. 다른 사람들에게 남겨주세요. – chux

+0

두 노드를 밀어 넣을 때만 공간을 할당하는 이유는 무엇입니까? – wildplasser

+0

현재 할당하지 않은 (현재 수행하지 않아야하는) 현재 세그먼트를 할당하지 않은 경우 seg fault는 어디에 있습니까? – RishiG

답변

2

하나의 명백한 오류는 목록 노드의 크기가 아니라 포인터 크기 비트 단위로 메모리를 할당하고 있다는 것입니다. 시도하고 당신의 mallocs에 변경 : 하나의 급습에 메모리 문제가 대부분 해결됩니다

ptr = malloc(sizeof(struct list)); // note the missing '*' 

I 내기를. 예를 들어, 비록 그것을 할당 한 후에도 현재 메모리를 덮어 씀으로써 메모리 누수가 발생했다면 (비록 다른 포스터가 말했듯이, 다른 포스터가 말하는 것처럼 그것은 필요하지 않습니다.)

+0

고마워요! 이것이 문제였습니다. – snl

1

푸시 할 때마다 새 목록 (여기 current)을 할당하면 안됩니다. 단지 head을 가리 키도록하십시오. 여기에 목록을 할당하고 바로 뒤에이 목록에 대한 포인터를 지정하여 head을 가리 킵니다. 따라서 할당 할 필요가 없습니다.

할당은 프로그램에 의해 쓰기 가능한 충분한 공간을 만듭니다. 포인터는 주소 만 저장하므로 주소가 0이 아닌 한 을 반복하는 한 주소에 대한 포인터가 변경되지 않으므로 원하는 위치에 포인터가 저장됩니다. head 대신.

나는 그 설명에서 자신을 잃어 버렸을 수도 있고 질문의 목적을 잃어 버렸을 수도 있지만 이것이 도움이되기를 바랍니다.

아, 마지막으로 tail->prev 지점을 head으로 설정해야합니다.

그러나 위 내 댓글에

3

을 바탕으로 당신의 머리에 1별로 1을 밀어 대신 초기화에 2 노드를 할당하는 이유를 나는 아직도 이해하지 못하고있다 : 당신은 또한해야

void init(int val){ 
    head = malloc(sizeof *head); 
    head->value = val; 
    head->next = NULL; 
    head->prev = NULL; 
    tail = head; 
} 

void push(int val){ 
    struct list *new; 
    new = malloc(sizeof *new); //allocate memory space for next side 
    new->value = val; 
    new->next = NULL; 
    new->prev = tail; 
    tail->next = new; 
    tail = new; 
} 

mallocNULL을 반환하지 않도록하십시오. 그러나 오류 처리가 모든 것을 망칩니다!

관련 문제