2016-04-02 7 views
1

I durch eine Liste von Schnittstellen am Looping versucht, eine IP-Adresse von jeder Schnittstelle zu greifen. Ich beobachte einen seltsamen Fehler, bei dem die Variable char * router_ip0 auf den Wert jeder anderen nachfolgenden Variablen aktualisiert wird, die ich in der Schleife gesetzt habe.IP-Adresse char * Variablen zu ändern, wenn unerwartet Looping-Adressen zu sammeln, von ifa_addr

char *router_ip; 
char *router_ip0; 
char *router_ip1; 
char *router_ip2; 
char *router_ip3; 
sockaddr_in *sa; 

//Loop through list of interface's 
for(tmp = ifaddr; tmp!=NULL; tmp=tmp->ifa_next){ 
    //Harvest IP address's 
    if(tmp->ifa_addr->sa_family==AF_INET){ 
     if(!strncmp(&(tmp->ifa_name[3]),"eth0",4)){ 
      printf("\nin 0\n"); 
      sa = (struct sockaddr_in *) tmp->ifa_addr; 
      router_ip0 = inet_ntoa(sa->sin_addr); 
      printf("IP addr0: %s\n", router_ip0); 
     } 
     else if(!strncmp(&(tmp->ifa_name[3]),"eth1",4)){ 
      printf("\nin 1\n"); 
      sa = (struct sockaddr_in *) tmp->ifa_addr; 
      router_ip1 = inet_ntoa(sa->sin_addr); 
      printf("IP addr0: %s\n", router_ip0); 
     } 
     else if(!strncmp(&(tmp->ifa_name[3]),"eth2",4)){ 
      printf("\nin 2\n"); 
      sa = (struct sockaddr_in *) tmp->ifa_addr; 
      router_ip2 = inet_ntoa(sa->sin_addr); 
      printf("IP addr0: %s\n", router_ip0); 
     } 
     else{ 
      printf("\nin 3\n"); 
      sa = (struct sockaddr_in *) tmp->ifa_addr; 
      router_ip3 = inet_ntoa(sa->sin_addr); 
      //printf("IP addr: %s\n", router_ip1); 
     } 

} 

Die Ausgabe ist wie folgt. Ich bin ziemlich sicher, dass es verifiziert werden kann, dass jede Variable nur einmal in der Schleife gesetzt wird. Ich vermute, dass es etwas damit zu tun hat, einen Zeiger auf einen anderen Zeiger mit char * und dem sa-> sin_addr-Zeiger zuzuweisen.

in 0
IP ADDR0: 10.0.0.1

in 1
IP ADDR0: 10.1.0.1

in 2
IP ADDR0: 10.2.0.1

Wie Sie sehen können, wird der Wert von router_ip0 auf den Wert von router_ip1 bzw. router_ip2 geändert. Die Schleife greift in diesem Beispiel nicht auf die Schnittstelle 3 zu. Wenn ich die Zuweisung von router_ip1 und router_ip2 auszukommen bekomme ich die erwartete Ausgabe

in 0 IP ADDR0: 10.0.0.1

in 1 IP ADDR0: 10.0.0.1

in 2 IP addr0: 10.0.0.1

Es wäre eine große Hilfe, wenn jemand erklären könnte, was hier vor sich geht. Vielen Dank!

Antwort

1

Sie müssen malloc und strcpy verwenden, um die zurückgegebenen Zeichenfolge zu zugewiesenen Speicher zu speichern. Gerade jetzt alle Ihrer char Zeiger verweisen auf die gleiche Adresse auf dem Stapel, an der zurückgegebenen Zeichenfolge von inet_ntoa, die gelöscht werden, wenn Sie den Bereich verlassen und dann in der nächsten Schleife neu erstellt. Dies überschreibt den Stapelspeicher, der die letzte zurückgegebene Zeichenfolge enthielt, so dass es so aussieht, als ob sich Ihre Variablen geändert hätten.

Zum Beispiel vor Ihrer for Schleife, könnten Sie tun:

char *result; 
router_ip0 = (char*)malloc(16); 
router_ip1 = (char*)malloc(16); 
router_ip2 = (char*)malloc(16); 
router_ip3 = (char*)malloc(16); 

(16 = maximale Länge einen IPv4-String + 1 für null Beendigung char)

dann in der if Blöcken der Schleife:

... 
if(!strncmp(&(tmp->ifa_name[3]),"eth0",4)){ 
    printf("\nin 0\n"); 
    sa = (struct sockaddr_in *) tmp->ifa_addr; 
    result = inet_ntoa(sa->sin_addr); 
    strcpy(router_ip0, result); 
    printf("IP addr0: %s\n", router_ip0); 
} 
else if... 

dann nach der Schleife:

free(router_ip0); 
free(router_ip1); 
free(router_ip2); 
free(router_ip3); 

Sie können auch char-Arrays der Größe 16 anstelle von char-Zeigern verwenden, um denselben Effekt zu erzielen, ohne sich um malloc und free kümmern zu müssen.