Ошибка сегментации при поиске имени хоста и IP-адреса - PullRequest
6 голосов
/ 25 мая 2010

У меня есть следующий фрагмент кода для получения имени хоста и IP-адреса,

#include <stdlib.h>
#include <stdio.h>
#include <netdb.h> /* This is the header file needed for gethostbyname() */
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>


int main(int argc, char *argv[])
{
struct hostent *he;

if (argc!=2){
printf("Usage: %s <hostname>\n",argv[0]);
exit(-1);
}

if ((he=gethostbyname(argv[1]))==NULL){
printf("gethostbyname() error\n");
exit(-1);
}

printf("Hostname : %s\n",he->h_name); /* prints the hostname */
printf("IP Address: %s\n",inet_ntoa(*((struct in_addr *)he->h_addr))); /* prints IP address */
}

Но я получаю предупреждение во время компиляции:

$cc host.c -o host
host.c: In function ‘main’:
host.c:24: warning: format ‘%s’ expects type ‘char *’, but argument 2 has type ‘int’

Тогда при запуске кода возникает ошибка сегментации:

./host 192.168.1.4
Hostname : 192.168.1.4
Segmentation fault

В чем ошибка в коде?

Ответы [ 5 ]

8 голосов
/ 22 сентября 2011

У меня был похожий код (если не тот же самый), и он прекрасно скомпилировался на машине в нашей школьной лаборатории, но когда я скомпилировал его на своей машине дома, у меня была та же ошибка (я не редактировал код ). Я прочитал справочную страницу для inet и обнаружил, что мне не хватает одного файла заголовка, то есть #include <arpa/inet.h>. После того, как я добавил этот заголовок в свою программу на C, он скомпилировался и нормально работал.

6 голосов
/ 25 августа 2010

Предупреждение о несоответствии для формата printf является важным предупреждением. В этом случае это происходит потому, что компилятор думает, что функция inet_ntoa возвращает int, но вы указали ожидать строку в строке формата.

Неверный тип возврата для inet_ntoa является результатом старого правила C, которое гласит, что если вы пытаетесь использовать функцию без предварительного объявления, то компилятор должен предположить, что функция возвращает int и принимает неизвестное (но фиксированное) количество аргументов. Несоответствие между предполагаемым типом возвращаемого значения и фактическим типом возвращаемого значения функции приводит к неопределенному поведению, которое в вашем случае проявляется как сбой.

Решение состоит в том, чтобы включить правильный заголовок для inet_ntoa.

1 голос
/ 12 сентября 2010

Взломать этот код:

printf("IP Address: %s\n",inet_ntoa(*((struct in_addr *)he->h_addr)));

В это:

struct in_addr* address = (in_addr*) he->h_addr;
char* ip_address = inet_ntoa(*address);
printf("IP address: %s\n", ip_address);

Это также облегчает отладку и точное определение проблемы.

0 голосов
/ 26 мая 2010

Вы можете попробовать сбросить значение he->h_addr, прежде чем пытаться разыменовать его и передать inet_ntoa. Если бы это было NULL, это привело бы к ошибке сегмента.

Как насчет запуска через strace?

0 голосов
/ 25 мая 2010

На самом деле, я просто скомпилировал этот код на моей машине с FreeBSD дома, и он работает.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...