[질문] Segmentation fault
현재 gdb에서 디버깅을 하다가 문제가 되는 부분의 코드를 유심히 보았지만 왜 자꾸 segmentation fault가 나는지를 모르겠습니다.
한 수 가르침을 부탁드립니다.
참고로 제가 직접 짠 코드는 아닙니다.
공부하려고 받은 코드인데 수정작업중입니다.
하다가 결국 이 부분에서 막혀서 질문란에 올린 것이니 왜 어렵게 코드를 작성했느니 인자값을 왜 그렇게 넣었냐느니 물으시면 저로서도 할말이 없습니다.
아래부터 코드입니다.
/*
* 저장된 채널의 주파수값을 읽어오는 함수
*/
unsigned long int channel_to_freq(int get_channel, int freq_type) { struct channel *tmp_channel; long ret_freq; int channel_tmp, cnt; tmp_channel = get_channel_list(freq_type); cnt=0; while(1) { channel_tmp = atoi((tmp_channel+cnt)->ch_num); if( channel_tmp == get_channel ) break; cnt++; } ret_freq = atol((tmp_channel+cnt)->ch_freq); return ret_freq; }
이 함수는 메인 함수에서
current_freq = channel_to_freq( 1, FQBCAST); 로 콜됩니다.
자료형은 unsigned long current_freq; 입니다.
channel_to_freq 함수의 프로토 타입은 아래와 같습니다.
_____________________________________________
/*주파수 타입을 입력 받아 채널정보가 기록된 버퍼의 주소값 리턴*/
unsigned long int channel_to_freq(int get_channel, int freq_type);
------------------------------------------------------------------------
구조체 channel은 다음과 같습니다.
struct channel { char ch_name[5]; //채널 이름 char ch_num[3]; //채널 넘버 char ch_freq[7]; //주파수 // long ch_freq_int; //주파수 };
gdb툴로 메인 함수의 current_freq = channel_to_freq( 1, FQBCAST); 부분을 breakpoint로 잡고 running을 해봤습니다.
실행되다가 signal SIGSEGV를 나타내었고, backtrace를 해봤더니 아래와 같은 메시지가 나왔습니다.
_____________________________________________
(gdb) bt
#0 0x4202b0fa in __strtol_internal() from /lib/tls/libc.so.6
#1 0x42028839 in atoi() from /lib/tls/libc.so.6
#2 0x0804b8b6 in channel_to_freq()
#3 0x0804e1aa in main(argc=1, argv=0xbffff6b4) at xxxxx-1.0.c:628
#4 0x42015574 in __libc_start_main() from /lib/tls/libc.so.6
(gdb)
여기에서 보니 atoi() 함수가 문제가 되는거 같거든요.
뭐가 문제인지 부탁 좀 드립니다. 여러분
Re:
(tmp_channel+cnt)->ch_freq
atoi() 의 인자로 넘어간 이 코드의 의도가 무엇이신지요? 제가 보기에는 get_channel_list() 가 struct channel 의 array 를 리턴하기 때문에 그 array 를 이용하기 위해서 저런 코드를 작성하신거 같네요..만약에 그래서 저렇게 했다면,
저 부분에서 Segmentation fault 가 되겠네요.
어째서인지는 조금만 생각해 보시면 아실듯 싶네요.
인자값이요
kslee80님,
atoi 함수의 인자값이 (tmp_channel+cnt)->ch_freq가 아니라(tmp_channel+cnt)->ch_num을 말씀하시는거죠?
Re: [질문] Segmentation fault
포인터를 리턴하게 한다면 항상 포인터의 유효성(valid?)을 검사하세요.
루프에서 (tmp_channel+cnt)가 valid한가?검사후 처리
대략 아래를,
channel_tmp = atoi((tmp_channel+cnt)->ch_num);
다음과 같이....
대략 위와 같은 유형이겠습니다.
* 총체적으로, cnt값이 유효한가?검사하는게 옳겠습니다.
* cnt가 가질수 있는 최대치, 또는 그 배열의 마지막에 0(NULL)이 들어 있는지를 검토하세요.
Re:
의도적으로 어렵게 쓴 코드죠. :)
tmp_channel[cnt].ch_freq 라고 썼으면 읽기 쉬웠겠죠?
그리고 ch_num이나 ch_freq가 숫자라면 배열을 쓰지 말고 바로 int형을 쓰는게 어떨까요?
ch_num 등은 '\0'으로 끝나겠죠?
그리고 5/3/7바이트처럼 정렬하기 힘든 크기를 준 이유라도?
답변 감사합니다.
참고로 제가 직접 짠 코드는 아닙니다.
공부하려고 받은 코드인데 수정작업중입니다.
하다가 결국 이 부분에서 막혀서 질문란에 올린 것이니 왜 어렵게 코드를 작성했느니 인자값을 왜 그렇게 넣었냐느니 물으시면 저로서도 할말이 없습니다.
가급적 많은 답변을 보고 싶습니다.
Svn 에서 특정버전의 특정파일이 업데이트가 되지 않습니다.
Svn 에서 특정버전의 특정파일이 업데이트가 되지 않습니다.
현재는 200 버전을 넘어 있는데
188 에서 191 까지 특정 파일을 업데이트할때 문제가
read strings fail 이라는 비슷한 멘트가 발생됩니다
이문제를 해결하기 위해 뭐를 하면 될까요..??
ch_num[] 혹은 ch_freq[] 가 null-terminated
ch_num[] 혹은 ch_freq[] 가 null-terminated string 이 아닌가 보내요.
허접 질문..
그런데 재수가 없어서 ... break; 에 안걸리면..
저 While loop 는 언제 끝나나요?
댓글 달기