Не выводится ip хоста, функция getaddrinfo

struct sockaddr_in* addr;
struct addrinfo *hints;
struct addrinfo servinfo;
memset (&servinfo, 0, sizeof (servinfo));
servinfo.ai_family=AF_INET;
servinfo.ai_socktype=SOCK_STREAM;
int i=getaddrinfo("www.google.com","80",&servinfo,&hints);

addr=(struct sockaddr_in*)hints->ai_addr;
printf("ip: %s\r\n",inet_ntoa(addr->sin_addr));

Пытаюсь вывести ip хоста(гугла), но вылезает ошибка сегментирования, также пробовал вывести так:

printf("ip: %s\r\n",hints->ai_addr->sa_data);

но и здесь вылезает та же ошибка.


В целях удобочитаемости, здесь я убрал все проверки на ошибки, но в моем коде они присутствуют, никакие ошибки не вылезают, getaddrinfo отрабатывает как надо, наверное ошибка в последних двух строчках:

addr=(struct sockaddr_in*)hints->ai_addr;
printf("ip: %s\r\n",inet_ntoa(addr->sin_addr)); 

Что я не правильно сделал? Весь код:

#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <signal.h>
#include <unistd.h>
#include <string.h>
#include <netdb.h>
void sendall(int socket,char*buf,int size);
int recvall(int socket,char*buf,int size);
int main(int argc, char const *argv[])
{
    int sock=socket(AF_INET,SOCK_STREAM,0);
    struct sockaddr_in* addr;
    addr->sin_family=AF_INET;
    addr->sin_port=htons(80);

    struct addrinfo *hints;
    struct addrinfo servinfo;
    memset (&servinfo, 0, sizeof (servinfo));
    servinfo.ai_family=AF_INET;
    servinfo.ai_socktype=SOCK_STREAM;
    int i=getaddrinfo("www.google.com","80",&servinfo,&hints);/*servinfo 
задает параметры возвращаемых адресов
т.е если мы сделаем так servinfo.ai_socktype=SOCK_STREAM;, то нам 
вернутся 
адреса хостов работающих на tcp сокетах*/
//в hints записывается вся информация о хосте
    if(i!=0){
        perror("getaddrinfo");
        printf("%d\n",i );
    }
    switch(i){
        case EAI_FAMILY:printf("EAI_FAMILY\n");break;
        case EAI_SOCKTYPE:printf("EAI_SOCKTYPE\n");break;
         case EAI_BADFLAGS:printf("EAI_BADFLAGS\n");break;
        case EAI_NONAME:printf("EAI_NONAME\n");break;
        case EAI_SERVICE:printf("EAI_SERVICE\n");break;
        //case EAI_ADDRFAMILY:printf("EAI_ADDRFAMILY\n");break;
        //case EAI_NODATA:printf("EAI_NODATA\n");break;
        case EAI_MEMORY:printf("EAI_MEMORY\n");break;
        case EAI_FAIL:printf("EAI_FAIL\n");break;
        case EAI_AGAIN:printf("EAI_AGAIN\n");break;
        case EAI_SYSTEM:printf("EAI_SYSTEM\n");break;

    }
    //addr.sin_addr.s_addr=htonl(getipaddr.h_name);
     addr=(struct sockaddr_in*)hints->ai_addr;
    printf("ip: %s\r\n",inet_ntoa(addr->sin_addr));

    return 0;
}
void sendall(int socket,char*buf,int size)
{
    short int len,total=0;
    do{
        if((len=send(socket,&buf[total],size-total,0))==-1){
            perror("sendall");
            exit(1);
        }
       total+=len;
    }while(total!=len);
}
int recvall(int socket,char*buf,int size)
{
    short int total=0,len;
    do{
    len=recv(socket,&buf[total],size-total,0);
    fprintf(stderr, "asdasdasdasdasd,total%dlen%d\n",total,len );
    switch(len){
        case -1:
       perror("recv2");
       exit(1);
       case 0:
       return 0;
    }
    total=total+len;
     }while(buf[total-1]!='\0');
    return total;
}

Ответы (1 шт):

Автор решения: AlexGlebe

Я удалил необдуманное присвоение в область неизвестной памяти здесь :

struct sockaddr_in* addr;
//addr->sin_family=AF_INET;
//addr->sin_port=htons(80);

и всё пашет:

$ ./sockaddr 
ip: 17x.19x.22x.14x
→ Ссылка