2014-12-03 2 views
-2

C 프로그램 기능에 어려움이 있습니다. 함수 아이디어는 연결된 목록의 끝에 항목 (newval)을 추가하는 것입니다. 여기 내 코드는 (또한 그것으로 주석을 찾을 수) :링크 된 목록의 끝에 항목 추가 -> 오류

#include <stdlib.h> 

struct list 
{ 

    int val; 
    struct list *next; 
}; 

void add_to_list(struct list *l, int newval) 

{ 

    if (!l) return; //my fried said that I should add this, but I dont really understand why. 
        //and should it be if(l == NULL) rather than if(!l)? 
    while(l->next !=NULL) // I am pretty sure that this while loop is correct 
     l=l->next; 
    l->next = malloc(sizeof(int)) //hmm... is this correct way to allocate memory 
    l->next->val = newval; //not sure about this 
    l->next->next = NULL; //This should be fine 
} 
+0

'l-> next = malloc (sizeof (int))'실제로 메모리를 할당하는 올바른 방법이지만 충분하지는 않습니다. 전체'struct list'를 포함 할만큼 충분히 할당 할 필요가 있습니다. 이 라인을'l-> next = malloc (sizeof (* (l-> next)))로 바꾼다.' –

답변

0

가 대신

l->next = malloc(sizeof(int)); 

l->next = malloc(sizeof(struct list)); 

을 할당하고 제로에 할당 된 메모리 초기화해야합니다

memset(l->next, 0, sizeof(struct list)); 
+0

나는 동의하지 않는다. 구조를 초기화하기 위해'memset()'을 사용해야하는 이유는 무엇입니까? 이것은 그것을 보증 할만한 충분한 크기의 추억이 아닙니다. –

+0

OK,이 줄에서는 l-> next-> next = NULL -> memset이 중복되는 것을 보지 못했습니다. 나는 모든 것이 제대로 초기화되도록하고 싶었다. 내가 아는 한 memset은 메모리 덩어리의 가능한 가장 작은 크기 (1 바이트)에서 잘 작동한다. – chrmue

2
l->next = malloc(sizeof(int)); 

당신은 int

l->next = malloc(sizeof(struct list)); 

if(!l) 대한 구조하지에 메모리를 할당 할 필요가 귀하의 기능이 void로 선언 같은

+0

if (! l)은 if (l == NULL)와 실제로 동일합니까? 나는 (l)이 (l == 0)이라는 것을 의미한다고 생각했다. –

+0

@NerdBergg NULL이 0입니다.이 항목을 확인하십시오. http://stackoverflow.com/questions/1296843/what-is-the-difference-between-null-0-and-0 – Gopi

+0

알겠습니다. 분명하지만 다시, 이유는 무엇입니까? 여기에 문장이 있다면 위장 해? 내 말은,이 검사는 목록이 비어 있으면 반환한다는 것을 의미합니다. 하지만 왜 반환, 목록이 비어 있다면, 우리는 여전히 거기에 항목을 newval 추가 할 수 있습니까? 또는 목록이 비어 있다면 끝까지 추가 할 수 없다는 것을 의미합니까? 우리는 먼저 첫 번째 항목을 추가해야하며 다른 기능으로 수행해야합니다. –

0
void add_to_list(struct list *l, int newval) 

if(l == NULL) 같습니다. 즉, 함수가 오류를 알릴 수있는 방법이 없습니다. 샘플 코드 인 에 대해서는 문제가 아니지만 적어도 알고 있어야하는 것은 분명합니다.

if (!l) return; //my fried said that I should add this, 
        //and should it be if(l == NULL) rather than if(!l)? 

구조체 (!l)(l != NULL)는 완전히 동일하다. NULL 때문인 것으로 정의되는 본 은 "널 포인터 상수"및 는 "널 포인터 상수"는 " 갖는 정수 상수 식의 값이 0 또는 캐스팅 같은 식 void *를 입력 " . 다른 단어의 경우 NULL은 0으로 평가됩니다.

while(l->next !=NULL) // I am pretty sure that this while loop is correct 
     l=l->next; 

예,이 while 루프가 맞습니다. 루프가 완료되면 l은 으로 목록의 마지막 요소를 가리 킵니다.

l->next = malloc(sizeof(int)) //hmm... is this correct way to allocate memory 

할당량이 거의 맞습니다. 에 충분한 저장소를 할당하는 경우 int을 보유하지만 실제로는 하나의 저장소를 보유 할 충분한 공간이 필요합니다. struct list. 대신 l->next = malloc(sizeof(struct list));을 사용하십시오.

l->next->val = newval; //not sure about this 

여기에 오류가 없습니다. 이것은 다음 줄이 정확히 정확합니다.

l->next->next = NULL; //This should be fine 

예, 괜찮습니다 ..이 부분의 코드는 이미 덮여 있었다 malloc(),

l->next = malloc(sizeof(int)) //hmm... is this correct way to allocate memory 
    l->next->val = newval; //not sure about this 
    l->next->next = NULL; //This should be fine 

여기에 사용되는 방법을 금지, 대부분 올바른 동안


그러나, 약간 이례적인 일이다. 새 메모리를 할당 할 때 포인터를 직접 l->next에 할당 한 다음 초기화해야하기 때문입니다. 더 일반적으로 이루어집니다 무엇

는 todeclare 포인터와 같은 기능, 의 시작 부분에 struct list *tmp = NULL 및 할당 할 때, tmp에 새 메모리를 할당 할 수 있습니다. 그런 다음 이 가리키는 새 목록 요소를 tmp으로 초기화하고 만 초기화 한 다음 현재 초기화 된 새 목록 요소를 목록의 끝에 추가하십시오. 약간 더 많은 코드가 포함되지만 은 새 목록 요소 을 생성하고 목록의 끝에 요소를 추가하는 두 단계를 분리합니다. 이런 식으로 일을 또한

void add_to_list(struct list *l, int newval) 
    { 
     struct list *tmp = NULL; 

     if (!l) return; // If no valid list, return. 

     tmp = malloc(sizeof(struct list)); // Allocate new list element 
     tmp->val = newval;     // and fill it up. 
     tmp->next = NULL; // End of the list always points nowhere. 

     while(l->next !=NULL) // find end of list. 
      l=l->next; 

     l->next = tmp; // Attach new list element to end. 

     return; 
    } 

l->next 포인터를 통해 값을 할당에서 을 발생할 수있는 잠재적 인 혼란을 방지 할 수 있습니다.

관련 문제