Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 从ifa_addr循环收集地址时,IP地址字符*变量意外更改_C_Sockets_Pointers_Networking_Ip Address - Fatal编程技术网

C 从ifa_addr循环收集地址时,IP地址字符*变量意外更改

C 从ifa_addr循环收集地址时,IP地址字符*变量意外更改,c,sockets,pointers,networking,ip-address,C,Sockets,Pointers,Networking,Ip Address,我在一个接口列表中循环,试图从每个接口获取一个IP地址。我观察到一个奇怪的bug,其中char*routerip0变量被更新为我在循环中设置的每个后续变量的值 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;

我在一个接口列表中循环,试图从每个接口获取一个IP地址。我观察到一个奇怪的bug,其中char*routerip0变量被更新为我在循环中设置的每个后续变量的值

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);
        }

}
输出如下。我相当确信可以验证每个变量在循环中只设置一次。我怀疑这可能与将一个指针分配给另一个带有char*和sa->sin_addr指针的指针有关

在0中
IP地址0:10.0.0.1

在1中
IP地址0:10.1.0.1

在2
IP地址0:10.2.0.1

如您所见,路由器_ip0的值分别更改为路由器_ip1和路由器_ip2的值。在本例中,循环不访问接口3。如果我注释掉路由器_ip1和路由器_ip2的分配,我会得到预期的输出

在0 IP地址0:10.0.0.1

在1 IP地址0:10.0.0.1

在2 IP地址0:10.0.0.1


如果有人能解释一下这里可能发生的事情,那将是一个很大的帮助。谢谢大家!

您需要使用
malloc
strcpy
将返回的字符串保存到分配的内存中。现在,所有
char
指针都指向堆栈上相同的地址,位于
inet\u ntoa
返回的字符串处,当退出作用域时,该字符串将被清除,然后在下一个循环中重新创建。这将覆盖包含上一个返回字符串的堆栈内存,使其看起来像变量已更改

例如,在执行
For
循环之前,可以执行以下操作:

char *result;
router_ip0 = (char*)malloc(16);
router_ip1 = (char*)malloc(16);
router_ip2 = (char*)malloc(16);
router_ip3 = (char*)malloc(16);
(16=IPv4字符串的最大长度+空终止字符的1)

然后在循环的
if
块中:

...
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...
然后在循环之后:

free(router_ip0);
free(router_ip1);
free(router_ip2);
free(router_ip3);
您还可以使用大小为16的字符数组而不是字符指针来实现相同的效果,而不必担心
malloc
free