세그멘테이션오류
글쓴이: jjjjrr / 작성시간: 화, 2003/06/10 - 2:48오전
안녕하세요
long int *add;
myent = gethostbyname(buf);
while(*myent->h_addr_list != NULL)
{
add = (long int *)*myent->h_addr_list;
printf("add = (long int *)*myent->h_addr_list\n");
myen->s_addr = *add;
printf("printf before\n");
이코드에서
myen->s_addr = *add; 여기서 세그멘테이션오류가 납니다
왜그럴까요
네트웍프로그램에서
쓰레드안의 코드입니다
부탁합니다
잠자야되는데....
Forums:
위글의 변수타입은 struct hostent *myent;
위글의 변수타입은
struct hostent *myent;
struct in_addr *myen;
long int *add;
입니다
*add에서 죽은것 같은데add = (long int *)*myent
*add에서 죽은것 같은데
add = (long int *)*myent->h_addr_list;
이 의심이 가는군요.
add의 값을 출력해보심이 좋겠네요.
*myent->h_addr_list가 long int*가 아니라
long int인지 확인 해보세요.
myent->h_addr_list의 타입을 잘몰라서 ...
그나저나 백수 언제 탈출하냐... ㅡㅡ; 배고파라.
.
struct in_addr *myen;
myen 이 단지 포인터이기 때문이 아닐까여?
그래서 할당되지 않은 메모리에 값을 대입할려니
세그멘트 에러가 날듯.
하면 될듯.
gethostbyname()은 buf에 해당 하는 주소정보를 제대로 찾았
gethostbyname()은 buf에 해당 하는 주소정보를 제대로 찾았다면 이 함수가 생성시킨[어쩌면 소켓 계층일지도 모르겠습니다만 정확한 호출하는 쓰레드마다 할당이 됩니다.] hostent구조체의 포인터를 반환합니다. 즉 myent가 가지고 있는 값은 이 구조체의 포인터겠죠. 만일 실패했다면 널을 반환하게 됩니다.
정상적으로 값을 반환했다면 위의 코드는 세그멘테이션 폴트가 나지 않습니다. 그래서 원인은 buf에 해당 하는 주소정보가 없는 경우가 되겠습니다.
일단 확실하게 myen->s_addr = *add;에서 세그멘테이션 폴트가 나는지 확인해 보세요.
님의 코드로 테스트해본 결과 정상적인 경우에는 에러가 나질 않습니다. 정상적인 경우라 함은 이 코드를 수행하는 컴퓨터의 이름을 buf에 넣은 경우 제대로 작동합니다. 하지만 그렇지 않은 경우엔 while(*myent->h_addr_list != NULL)에서 바로 세그멘테이션 폴트가 납니다.
세그멘테이션 폴트가 나는 시점을 정확하게 파악하시길 바랍니다.
printf("printf before\n"); 이코드가 실행되지않고
안녕하세요 답변감사합니다
프로그램을 실행해서 클라이언트가 접속하면
위코드가 실행됩니다
근데여
이런결과가 나옵니다
printf("printf before\n"); 이코드가 실행되지않고 오류가납니다
add에는 값이 들어있는데.....
여러가지로 테스트중입니다
또해봤더니
다시해봤읍니다
이렇게했더니
이렇게됩니다왜이럴까요
*add값이 - 값이나옵니다
[quote]이런결과가 나옵니다 printf("printf befor
가 아니라.
myen->s_addr = *add;에서 수행이 안되는것입니다.
찍힌 값을 보아하니 주소값으론 유효하지 않은 값입니다.
즉 add는 포인터입니다. 이 변수는 값으로 주소를 가지고 있습니다. 포인터앞에 *의 연산자를 사용할 경우 해당 값의 주소의 변수혹은 메모리블럭을 참조하여 실제 값을 얻어오는것입니다.
그런데 출력된 결과들을 보니 134529708, -598937040 의 값들은 주소로는 유효하지 않은 값들입니다. 그래서 이 주소를 참조하여 값을 얻어오는 경우 세그멘테이션 폴트가 나게 되는것입니다.
즉 다시 말해서 134529708나 -598937040에 번지수에 있는 실제 값을 가지고 오는 것입니다. -라면 당연히 유효하지 않은 값이겠죠. 그리고 134529708의 경우에는 heap혹은 stack의 영역이 아닙니다.
Re: 또해봤더니
add = (long int *)*myent->h_addr_list;
에 대해서 좀더 자세히 설명 드리겠습니다.
h_addr_list의 자료형은 char**로써 간단하게 char* 배열의 포인터로 생각하시면 되겠습니다.
myent->h_addr_list라 함은 char*의 배열중 첫인덱스의 주소를 가지고 있다고 생각하시면 됩니다.
그리고 *(포인터)는 주소가 가리키고 있는 값이라고 생각 하시면 됩니다. 그러면 실제로 add에 들어가는건 char*의 배열중 첫인덱스의 주소가 들어가는것이 아니라 이 주소의 실제 값이 들어가게 되는것입니다. 형변환을 아무리 long int*로 하셨다 하더라도 원천적인 값 자체가 유효한 주소값이 아니기 때문에 그 이후 라인에서 세그멘테이션 폴트가 나겠죠...
간단하게 h_addr_list의 값은 다음과 같다고 보시면 됩니다.
0xff667788 번지의 char*의 배열 addrlist의 값이
"defe", "daaa", "fffe" 라고 할때
h_addr_list = addrlist 가 내부적으로 연산이 수행될것입니다. 그리고 이 h_addr_list는 실제론 "defe"의 번지수를 가리키고 있다고 보시면 됩니다.
그래서 *myent->h_addr_list 하시면 "defe"가 얻어지게 됩니다. 즉 이건 주소가 아니죠?
그럼 전 이만...
잘못 생각하신듯..
주소가 맞습니다.
*myent->h_addr_list 는 주소값을 가지고 있습니다.
Re: 잘못 생각하신듯..
아 제가 잘못생각했군요... 정정하겠습니다. char*의 배열이라고 해놓구선 char*의 그냥 포인터라고 생각을 했습니다. 이런 오류를 범해서 잘못된 정보를 올리다니.. ㅜㅡ 죄송합니다.
근데 님의 소스코드를 수행해보면 그 부분에선 세그멘테이션 폴트가 나질 않는데요... 좀더 자세히 검토해 보시기 바랍니다.
세그멘테이션 폴트가 나면 아예 while에서 납니다.
혹시 모르니깐 이것도 체크해 보시기 바랍니다. 바운더리 에러[메모리 침범] 부분적인 코드만 보이니 일단은... 그리고 while문을 몇번째 반복할때부터 나는지도 검토하시기 바랍니다.
힌트: 제가 수행한 코드와 님의 코드의 차이점은 앞에 많은 님들이 답변 다신것 처럼 struct in_addr *myen부분입니다.
전 이부분을 메모리가 할당된 struct in_addr myen을 직접 썻구요. 아마도 님은 이부분이 잘못된것 같네요...
결국 전 답변 다는데 삽질했다는... 으으으 덕분에 저도 많은걸 배우고 갑니다. ㅜㅡ
zz
저도 포인터는 역시 헷갈릴때가 있는거 같아요.
개념을 마니 잡았다 싶어도 어느 순간에 살짝 헷갈리기 쉬운게
포인터 인듯.
그래서 C하면 포인터 떠올리는게 다 이유가 있나 봅니다..
저는 코드를 다르게 사용해서 고쳤읍니다
안녕하세요
답변감사합니다
저는 코드를 다르게 사용해서 고쳤읍니다
지금은 잘동작하고있읍니다
많은관심 감사드립니다
즐거운하루되세요
[/code]
댓글 달기