2011-04-10 2 views
0

포인터에 대한 작은 개념적 질문이 있습니다. 이것은 당황 스러울 지 모르지만 그 해답을 알아야합니다.C 포인터 질문

getline 함수를 사용하여 파일에서 한 줄을 읽으려고했습니다. getline은 첫 번째 인수로 char **를 취하며, 이는 라인 포인터가 저장되는 곳입니다. 아래의 붙여 넣은 코드를 확인하고 그 차이점을 알려주십시오. readLine 포인터의 선언과 사용에 주목하십시오.

두 번째 코드는 printf()에 도달했을 때 세그먼트 오류가 발생했습니다. printL() 전에 gdb로 * readLine의 값을 검사했는데 정확했지만 printf()로 갔을 때 붐 SIGSEGV

이 코드는 작동합니다 : FILE * fp;

char *readLine; 

readLine=NULL; 

int s=0; 

while(getline(&readLine,(size_t *)&s,fp) != -1){ 

    printf("%s\n",readLine); 

} 

이 코드는 작동하지 않습니다. FILE * fp;

char **readLine; 

*readLine=NULL; 

int s=0; 

while(getline(readLine,(size_t *)&s,fp) != -1){ 

    printf("%s\n",*readLine); 

} 

환호 ...이 32 비트의 int와 64 비트 시스템을 중단한다

+2

(사람에게 물고기 줄 것) 대신에 http://www.ericgiguere.com/articles/reading-c-declarations.html과 http://www.antlr.org/wiki를 읽는 것이 좋습니다./display/CS652/How + To + Read + C + Declarations (남자에게 물고기를 가르치기) –

+0

'works'라고 말하는 코드는 C로 프로그래밍하는 데 100 % 잘못된 방법입니다. 진행하기 전에 기본을 고쳐야합니다. 더 이상. – Donotalo

+1

@Donatalo : s는 size_t로 선언되어야하고, readLine을 NULL로 설정하는 것은 불필요합니다. 하지만 그렇지 않으면 나는 이것이 괜찮다고 생각한다; 100 % 잘못 된 것이 조금 가혹합니다. 아니면 다른 것을 놓치고 있습니까? –

답변

2
(size_t *)&s 

RV. 이런 종류의 문제에 대한 해결책은 필요한 타입 (size_t s;)을 선언하는 것입니다. x86-64에서는 스택의 4 바이트 위치에 8 바이트를 할당하므로 스택 손상이 발생합니다. 덮어 쓰기는 호출 된 함수에서 발생하기 때문에 반환 주소를 덮어 쓸 수 있습니다.

char **readLine; 

*readLine=NULL; 

이 또한 즉각적인 충돌입니다. 초기화되지 않은 포인터의 대상에 값을 할당하고 메모리의 알 수없는 지점에서 바이트를 변경합니다.

1

첫 번째 경우 변수 값인 readLine (값이 스택에 저장 됨, 자체 예약 영역)은 포인터에 대한 char입니다. getline()에 주소를 전달하면 getline()에 실제 포인터를 예약 된 메모리에 저장하도록 지시합니다. 모든 것이 작동합니다.

두 번째 경우, readLine은 char to pointer의 포인터이며 다시 스택에 공간이 예약되어 있습니다. 하지만 getline()을 호출하면 getline()에 readLine 변수에 char에 대한 포인터가 저장되어야하는 주소가 저장된다고 말합니다. 그러나 readLine은 어떤 임의의 메모리를 가리키고 있습니다. 은 getline()이 데이터를 저장하도록 허용해야하는 위치에이 아닙니다. 사실, 당신은 이미 말했듯 readline과 소유하지 않은 메모리를 가리키고 있기 때문에 당신이

*readLine = NULL; 

을 쓸 때 메모리 손상을 시작했습니다. getline()은 더 나쁘게 만듭니다.