Frage

Ich habe das folgende Stück Code für das Erhalten der Hostnamen und IP-Adresse,

#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 */
}

Aber ich bin eine Warnung während der Kompilierung bekommen:

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

Dann gibt es einen Segmentierungsfehler, wenn ich den Code ausführen:

./host 192.168.1.4
Hostname : 192.168.1.4
Segmentation fault

Was ist der Fehler im Code?

War es hilfreich?

Lösung

Die Warnung über die Nichtübereinstimmung für das printf-Format ist eine wichtige Warnung. In diesem Fall kommt es, weil der Compiler denkt, dass die Funktion inet_ntoa eine int zurückgibt, aber Sie angegeben eine Zeichenfolge im Format-String zu erwarten.

Die falsche Rückgabetyp für inet_ntoa ist das Ergebnis einer alten C-Regel die besagt, dass, wenn Sie versuchen, eine Funktion ohne vorherige Anmeldung zu verwenden, wird der Compiler die Funktion übernehmen muss eine int zurückgibt und eine unbekannte (aber fixiert ) Anzahl von Argumenten. Die Diskrepanz zwischen dem angenommenen Rückgabetyp und der tatsächlichen Rückgabetyp der Funktion führt zu undefinierten Verhalten, was sich als ein Absturz in Ihrem Fall.

Die Lösung ist die richtigen Header für inet_ntoa aufzunehmen.

Andere Tipps

Ich hatte einen ähnlichen Code (wenn nicht gleich) und es gut in unserem Schullabor in einer Maschine zusammengestellt, aber wenn ich es auf meinem Rechner zu Hause zusammengestellt, es hatte den gleichen Fehler (ich habe den Code nicht bearbeiten ). Ich las die Manpage inet, und fand, dass ich eine Header-Datei hatte fehlt, was der #include <arpa/inet.h> ist. Nachdem ich diesen Header meiner C-Programm hinzugefügt, es kompiliert und ausgeführt in Ordnung.

Break diesen Code:

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

In diesen:

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

Es macht es auch einfacher zu debuggen und lokalisieren, das Problem.

Eigentlich habe ich gerade kompiliert, dass Code auf meinem FreeBSD-Rechner zu Hause und es funktioniert.

Sie könnten versuchen, den Wert von he->h_addr Dumping bevor Sie versuchen, es zu dereferenzieren und es inet_ntoa passieren. Wenn es NULL ist, dass in einem seg Fehler führen würde.

Wie wäre es durch strace läuft?

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top