2010-05-25 23 views
6

tengo el siguiente fragmento de código para obtener el nombre de host y la dirección IP,Fallo de segmentación cuando al buscar el nombre de host y la dirección 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 */ 
} 

Pero estoy recibiendo una advertencia durante la compilación:

$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’ 

entonces hay un fallo de segmentación cuando corro el código:

./host 192.168.1.4 
Hostname : 192.168.1.4 
Segmentation fault 

¿Cuál es el error en el código?

+4

Estás haciendo algo horrible para una estructura inocente. – SLaks

+0

Por cierto, generalmente no debe usar 'gethostbyname' en el nuevo código, principalmente porque no es compatible con IPv6. Deberías usar 'getaddrinfo' en su lugar: http://beej.us/guide/bgnet/output/html/multipage/getaddrinfoman.html –

+0

¿Qué sucede si ejecutas ./host www.stackoverflow.com? Es decir, si lo usa con un nombre real en lugar de una dirección IP. – nsayer

Respuesta

6

La advertencia sobre la falta de coincidencia para el formato de impresión es una advertencia importante. En este caso, se debe a que el compilador está pensando que la función inet_ntoa devuelve int, pero especificó que esperaba una cadena en la cadena de formato.

El tipo de retorno incorrecto para inet_ntoa es el resultado de una antigua regla C que establece que si intenta utilizar una función sin una declaración previa, entonces el compilador debe asumir que la función devuelve int y toma un desconocido (pero fijo) número de argumentos. La falta de coincidencia entre el tipo de devolución supuesta y el tipo de devolución real de la función da como resultado un comportamiento indefinido, que se manifiesta como un bloqueo en su caso.

La solución es incluir el encabezado correcto para inet_ntoa.

0

En realidad, acabo de compilar ese código en mi máquina FreeBSD en mi casa y funciona.

+0

Lo intenté sin #include en Mac OS y estaba dando advertencia y tenía fallo de segmentación – Biranchi

0

Puede intentar eliminar el valor de he->h_addr antes de intentar desreferenciarlo y pasarlo a inet_ntoa. Si fue NULL, eso daría como resultado un fallo seg.

¿Qué le parece ejecutarlo a través de strace?

1

descifrar este código:

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

En esto:

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

También hace que sea más fácil de depurar y encontrar el problema.

8

Tenía un código similar (si no es el mismo) y compilaba bien en una máquina en el laboratorio de nuestra escuela, pero cuando lo compilé en mi máquina en casa, tenía el mismo error (no edité el código). Leí la página de manual para inet y encontré que faltaba un archivo de encabezado, que es el #include <arpa/inet.h>. Después de agregar ese encabezado a mi programa C, compiló y ejecutó bien.

+1

Funcionó para mí. ¡Muchas gracias! –

Cuestiones relacionadas