2013-02-14 1 views
4

이것은 과제물의 일부입니다.C char [] Warning 반환 "로컬 변수의 주소를 반환합니다."

getLine 메서드에서 한 줄의 파일을 읽고 반환하려고합니다.

char *getLine(FILE *input) { 
    char line[30]; 
    if(fgets(line, sizeof(line), input)!=NULL) 
    { 
     return line; 
    }else{ 
     return NULL; 
    } 
} 

이 내가 포인터에 대해 배운 적이없는에서 작동하는 것 같다, 그러나 나는 경고 메시지 warning: function returns address of local variable [enabled by default]을 제거 할 수 없습니다입니다. 이 경고는 라인 return line;을 나타냅니다. 필자는 컴파일 할 때 경고 나 오류가 없어야합니다. 내가 뭘 잘못하고 있는지 모르겠다.

내가 찾은 도움의 대부분은 텍스트 줄에 malloc-ing 공간을 제안했지만 다른 클래스에서 일부를 수행했지만 아직 수업에서 다루지 않았습니다. 정말이 일을하는 가장 좋은 방법입니까? 그렇다면 프로그램의 어느 곳에서나 자유롭게 할 수 있습니까?

+1

함수가 반환 될 때 지역 변수가 없어지면 매달린 포인터가 반환됩니다. 속임수를 찾게 해줘. –

+0

힙에 메모리를 할당하려면'malloc'을 사용하십시오. 그리고이 질문은 이미 수많은 질문을 받았습니다. – KBart

+0

이것은 꽤 흔한 실수이기 때문에이 문제가 발생했을 때 수십 개의 게시물을 찾을 수 있습니다 :)이 이유 중 하나는 대부분의 컴파일러가 여러분이하는 일에 대해 경고조차하지 않는다는 것입니다. http : // ideone. com/S5Se71 – LihO

답변

12

char line[30];은 자동 저장 기간이있는 어레이입니다. 실행중인 함수가 함수의 범위를 벗어나면 상주하는 메모리가 할당 해제되므로 반환하는이 포인터에 대한 포인터는 유효하지 않게됩니다 (매달린 포인터).

이미 할당이 해제 된 메모리에 액세스하려고하면 이 정의되지 않은 동작이됩니다.

당신은 당신의 배열을 동적으로 할당하고 호출자가 명시 적으로 할당을 취소 할 수 있습니다

: 내가 찾을 수있는만큼 지금까지 그 이전의 질문에 포함되지 malloc에를 사용하지 않고

char *getLine() { 
    char* line = malloc(30); 
    ... 
    return line; 
} 

// somewhere: 
char* line = getLine(); 
... 
free(line); 
+1

이 답변의 템플릿을 만들어야합니다 ..;) – KBart

4

대안 :

/* Warning, this function is not re-entrant. It overwrites result of previous call */ 
char *getLine(FILE *input) { 
    static char line[30]; 
    return fgets(line, sizeof(line), input); 
    /* fgets returns NULL on failure, line on success, no need to test it */ 
} 

설명 : function scopestatic variables은 함수가 반환 된 후에도 값을 유지합니다. 그러한 변수의 인스턴스는 하나 뿐이며, 같은 함수를 호출 할 때마다 동일한 인스턴스가 사용됩니다 (재진입/스레드로부터 안전하지는 않음). 정적 변수를위한 메모리는 프로그램이 시작될 때 할당된다. 그것은 힙이나 스택이 아니지만 프로그램의 메모리 공간을 실행하는 자신의 예약 영역이다. 정적 변수의 값은 처음 사용되기 전에 단 한 번만 초기화됩니다 (위의 값은 특정 초기화가 없으므로 0으로 채워지지만 초기 값도 가질 수 있으며 함수가 처음 호출 될 때 값이됩니다).

이런 식으로 정적 변수를 사용하는 것은 약간 해킹 된 것처럼 보일 수 있지만 여전히 표준 C에서도 사용되는 유효한 패턴입니다 (예 : with strtok() function). 또한 C 표준에도 strtok_r()이 있으므로 재진입 버전의 필요성을 보여줍니다. 로컬 표준 변수 대신 하나의 추가 매개 변수가 있기 때문에 사용하기가 더 복잡합니다.