strtok 을 통해 얻어진 토큰에 접근후 메모리 오류발생 문제
문제가 없었던 프로그램에 토큰을 이어붙인 스트링을 사용해야해서 밑의 함수를 추가 하였습니다.
세그폴트가 발생되어 밑의 코드들을 주석처리 해보니 다시금 정상작동 하더라구요..
노가다를 통해서 확인해본 결과
sprintf(psResult,"%s",psTemp);
strncpy(psResult, psTemp, strlen(psTemp));
memcpy(psResult, psTemp, strlen(psTemp));
세개중 하나의 함수로 strtok 의 결과물 psTemp 에 접근한 후에
다른함수에서 메모리 오류가 발생하네요..
printf 로 접근했을시에는 오류가 나지 않고
psResult에 "What" 이라는 임의의 값을 넣고 진행했을때도 오류가 나지 않더라구요...
이것이 당췌 무슨 이유에서인지 모르겠네요 ㅠㅠ
OS 는 HP-UX B.11.23 U ia64 2333129302 unlimited-user license 입니다.
[에러 케이스 1]
Program received signal SIGSEGV, Segmentation fault
si_code: 1 - SEGV_MAPERR - Address not mapped to object.
[Switching to thread 2 (system thread 245277)]
0x9fffffffe6ffbd70:0 in real_malloc+0x670 () from /usr/lib/hpux64/libc.so.1
(gdb) bt
#0 0x9fffffffe6ffbd70:0 in real_malloc+0x670 () from /usr/lib/hpux64/libc.so.1
#1 0x9fffffffe6ffb510:0 in _malloc+0x7d0 () from /usr/lib/hpux64/libc.so.1
#2 0x9fffffffe70066b0:0 in malloc+0x140 () from /usr/lib/hpux64/libc.so.1
#3 0x9fffffffe6fc2570:0 in calloc+0x200 () from /usr/lib/hpux64/libc.so.1
#4 0x9fffffffe77b4330:0 in 제가 만든 함수_1()
[에러 케이스 2]
Program received signal SIGSEGV, Segmentation fault
si_code: 1 - SEGV_MAPERR - Address not mapped to object.
[Switching to thread 2 (system thread 245565)]
0x9fffffffe6ffbd70:0 in real_malloc+0x670 () from /usr/lib/hpux64/libc.so.1
(gdb) bt
#0 0x9fffffffe6ffbd70:0 in real_malloc+0x670 () from /usr/lib/hpux64/libc.so.1
#1 0x9fffffffe6ffb510:0 in _malloc+0x7d0 () from /usr/lib/hpux64/libc.so.1
#2 0x9fffffffe70066b0:0 in malloc+0x140 () from /usr/lib/hpux64/libc.so.1
#3 0x400000000008f3d0:0 in 만든 함수_2()
인자값
("www.test.com", "." , 0 , 2 , str[LENGTH] ) 요롷게 들어값니다.
실행 결과는 str[LENGTH] = "www.test" 입니다.
int get_sequence_tokens(char * psTarget, char* psSeparator,int nStartPosition, int nNumTokens, char * psResult) { char psStr[LENGTH]; char * psTemp; int i; memset(psStr, 0x00, LENGTH); memset(psTempforFree, 0x00, LENGTH); strncpy (psStr, psTarget, strlen(psTarget)); psTemp = strtok(psStr, psSeparator); for (i=nStartPosition ; i<nNumTokens ; i ++){ if(i==nStartPosition){ //printf("psTemp['%s}\n",psTemp); //sprintf(psResult,"'%s",psTemp); //strncpy(psResult, psTemp, strlen(psTemp)); //memcpy(psResult, psTemp, strlen(psTemp)); //strncpy(psResult, "What",strlen("What")); continue; } if(NULL == (psTemp = strtok(NULL,psSeparator))) { return -1; } else{ //strcat(psResult, psSeparator); //strcat(psResult, psTemp); } } return 0; }
이코드가 에러가 난다는 말씀인가요?? $ cat
이코드가 에러가 난다는 말씀인가요??
$ gcc a.c
$ ./a.out
str="wwww.test"
}}}
네.
정확히는 이 코드에서 에러가 나는것은 아니구요
이 코드를 추가한후에 함수를 실행시키면
다른 곳에서 오류가 납니다.
제가 만든 함수_1번또는 함수_2번에서요.. 공통점은 gdb 결과에서 보시듯이 malloc 부분이구요...
복사관련된 함수를 주석처리하면 (sprintf 또는 strncpy 또는 memcpy)
malloc 관련 에러가 발생하지 않습니다
뭔가... 이 코드가 메모리 영역을 망가뜨리는건 아닐런지요...
strncpy()의 세번째 인자가 잘못된 것 같군요.
strncpy()의 세번째 인자가 잘못된 것 같군요.
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
Korean Ver: http://cinsk.github.io/cfaqs/
코드만 보고 이야기 하면, 버퍼크기문제가 없다고
코드만 보고 이야기 하면, 버퍼크기문제가 없다고 가정했을때
sprintf(psResult,"%s",psTemp);는 문제를 일으킬것 같지않고.
이 두가지는
strncpy(psResult, psTemp, strlen(psTemp));
memcpy(psResult, psTemp, strlen(psTemp));
문제를 일으킬거예요 psResult가 null-termination이 안되니까 strcat()이 나중에 호출되면 psResult다음의 내용에 따라 concatenation이 어떤 위치에서 시작할지 알수가 없죠. 윗분 말한게 이 내용인듯 하네요.
strncpy(psResult, psTemp, strlen(psTemp)+1);이나
memcpy(psResult, psTemp, strlen(psTemp)+1); 로 하던가
strcpy (psResult, psTemp)하면 되는데요. psTemp는 strtok()에 의해 이미 null-terminate되어 있으니까요.
댓글 달기