2016-07-04 3 views
0

다음 코드에서 C로 포인터로 구현 된 기본 정수 연결 목록을 볼 수 있습니다. 새로운 int- 목록 앞의 val. 이 두 함수는 동등하지만 출력에서는 그렇지 않다고 생각했습니다.C : 연결된 목록 - 함수 "insert first"가 예상대로 작동하지 않습니다.

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

typedef struct _IntlistElem* Intlist; 
typedef struct _IntlistElem {int val; Intlist next;} IntlistElem; 

Intlist insertfirst(int val, Intlist list) { 
    Intlist new = malloc(sizeof(IntlistElem)); 
    new->val = val; 
    new->next = list; 

    return new; 
} 

Intlist insertfirstAlternative(int val, Intlist list) { 
    IntlistElem new = {val, list}; 
    Intlist head = &new; 

    return head; 
} 

void print(Intlist l){ 
    while (l!=NULL){ 
     printf("%d\n", l->val); 
     l = l->next; 
    } 
printf("_____\n"); 
} 

int main(){ 
    Intlist ls = NULL; 
    ls = insertfirst(2, ls); 
    ls = insertfirst(1, ls); 
    print(ls); 

    Intlist lsAlt = NULL; 
    lsAlt = insertfirstAlternative(2, lsAlt); 
    lsAlt = insertfirstAlternative(1, lsAlt); 
    print(lsAlt); 

    return 0; 
} 

출력 : 질문

1 
2 
_____ 
1 
1 
... 

을하는 내 :
이 왜 인쇄 기능이 종료되지 않는 이유는 무엇입니까? (대체 함수를 호출 한 후)
2. 이 2 개의 "insertfirst"함수가 예상했던 것과 다른 이유는 무엇입니까?
이러한 기능의 차이점은 무엇입니까?

나는 귀하의 답변을 기다리고 있습니다. :)

+0

한 줄씩 단계별로 실행할 때 디버거를 사용하여 코드 흐름과 현재 변수 값을 검사하는 방법을 긴급히 알아야합니다. –

+1

'Intlist head = &new;':'new'는 지역 자동 변수입니다. 범위 밖에서는 유효하지 않습니다. – BLUEPIXY

+0

이 코드는 경고 플래그 (gcc는 -Wall -Werror -Wextra)와 함께 컴파일되지 않습니다. 나는 당신이 다음에 그것들을 사용할 것을 권합니다. – qleguennec

답변

1

함수 insertfirstAlternativehead에 대한 포인터를 반환합니다. 변수의 수명은 함수의 반환 시점에서 끝납니다. 따라서 잘못된 포인터 값을 반환합니다.

포인터가 가리키는 개체의 수명이 끝나면 포인터의 값이 불확실 해집니다.

아무거나 일어날 수 있습니다.

두 번째로 함수를 호출하면 두 번째 head이 첫 번째와 동일한 주소에 만들어 지므로 next 포인터가 같은 개체를 가리 킵니다. 그러므로 무한 루프.

+0

먼저 감사합니다. 그러나 할당 된 IntlistElem 변수 "new"가 "insertfirst"가 종료 된 후에도 계속 살아있을 가능성이 있습니다. – CptCook

+0

살아남지 못합니다. 효율성을 위해 메모리는 지워지지 않고 주소에서 (매달린 포인터를 통해) 종류의 작업을 읽습니다. 그러나 이것은 단지 우연한 일입니다. 그 사이에 다른 기능을 호출하면 메모리가 재사용되고 덮어 쓰게됩니다. –

+0

감사합니다. 그래서 이것은 연결된 목록이 "안전"할 수있는 방법이 없음을 의미합니까? – CptCook

관련 문제