みんなの「教えて(疑問・質問)」にみんなで「答える」Q&Aコミュニティ

こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

締切り済みの質問

getaddrinf()で取得したIPアドレス表示

お世話になります。

C言語でソケット通信の勉強中です。
CentOS6.4を使っています。

LIST1は、
IPアドレスではなくホスト名がコマンド引数で渡されたとき、
getaddrinfo()でIPアドレスを取得して、
sendto()でサーバにメッセージを送信するだけの、
クライアントのプログラムです。

このLIST1のudp通信自体は上手くいくのですが、
終わりの方で、
getaddrinfo()で取得したIPアドレスを
inet_ntoa()を使って文字列表示しようとすると、
セグメンテーション違反です (コアダンプ)となってしまいます。

inet_ntoa()の引数が疑わしく、
いろいろ渡し方を変えたり、参照方法を変えたりしてみたのですが、、
なかなか解決しません。

ちゃんと、192.168.12.1とか表示するにはどうすれば良いでしょうか?


■LIST1

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <errno.h>
int
main(int argc,char *argv[]){
int sock;
struct addrinfo hints,*res;
int n;
int err;
if(argc != 2){
fprintf(stderr,"Usage : %s dst \n",argv[0]);
return 1;
}
/* IP アドレス表記+ホスト名両方に対応 */
memset(&hints,0,sizeof(hints));
hints.ai_family = AF_UNSPEC; /* IPV4 IPV6 両方に対応 */
hints.ai_socktype = SOCK_DGRAM;
err = getaddrinfo(argv[1],"12345",&hints,&res);
if(err != 0){
perror("getaddrinfo");
printf("getaddrinfo %s\n",strerror(errno));
printf("getaddrinfo : %s \n",gai_strerror(err));
return 1;
}

sock = socket(res->ai_family,res->ai_socktype,0);
if(sock < 0){
perror("socket");
return 1;
}
{
const char *ipverstr;
switch (res->ai_family){
case AF_INET:
ipverstr = "IPv4";
break;
case AF_INET6:
ipverstr = "IPv6";
break;
default:
ipverstr = "unknown";
break;

}
printf("ipverstr = %s\n ",ipverstr);


}
n = sendto(sock,"HELLO",5,0,res->ai_addr,res->ai_addrlen);
//n = sendto(sock,"HELLO", 5, 0,(struct sockaddr *)addr, sizeof(addr));
if(n<1){
perror("sendto");
{

}
return 1;
}

printf("############ finish !! #######\n");
close(sock);
freeaddrinfo(res);
struct sockaddr_in *addr;
addr = (struct sockaddr_in *)res->ai_addr;
printf("inet_ntoa(in_addr)sin = %s\n",inet_ntoa((struct in_addr)addr->sin_addr));
return 0;
}

投稿日時 - 2013-11-20 17:53:03

QNo.8355080

困ってます

このQ&Aは役に立ちましたか?

2人が「このQ&Aが役に立った」と投票しています

回答(1)

ANo.1

典型的なuse after freeに見えますが?

> freeaddrinfo(res);
でresを開放して、
> struct sockaddr_in *addr;
> addr = (struct sockaddr_in *)res->ai_addr;
と、開放した値を参照しているようですが?

freeaddrinfoしたらその中のすべての値は解放されますよね。

投稿日時 - 2013-11-20 22:40:42

補足

大変申し訳ありません。
LIST1として掲載するソースのバージョンを間違えていました。freeaddrinfo()よりも前、"###finish !!###"の直前で実施しているものがあり、そちらでもセグメンテーション違反となってしまいます。

よろしくお願いします。

投稿日時 - 2013-11-21 09:07:45

お礼

ご回答ありがとうございます。

投稿日時 - 2013-11-21 09:07:47

あなたにオススメの質問