gpt4 book ai didi

c - IP 地址 char* 变量在循环从 ifa_addr 收集地址时意外更改

转载 作者:太空宇宙 更新时间:2023-11-04 03:31:18 24 4
gpt4 key购买 nike

我正在遍历一个接口(interface)列表,试图从每个接口(interface)获取一个 IP 地址。我观察到一个奇怪的错误,其中 char* router_ip0 变量被更新为我在循环中设置的每个其他后续变量的值。

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 指针将指针分配给另一个指针有关。

in 0
IP addr0: 10.0.0.1

in 1
IP addr0: 10.1.0.1

in 2
IP addr0: 10.2.0.1

如您所见,router_ip0 的值分别更改为 router_ip1 和 router_ip2 的值。在此示例中,循环不访问接口(interface) 3。如果我注释掉 router_ip1 和 router_ip2 的分配,我会得到预期的输出

in 0 IP addr0: 10.0.0.1

in 1 IP addr0: 10.0.0.1

in 2 IP addr0: 10.0.0.1

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

最佳答案

您需要使用mallocstrcpy 将返回的字符串保存到分配的内存中。现在你所有的 char 指针都指向堆栈上的相同地址,即从 inet_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 block 中:

...
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 的 char 数组而不是 char 指针来实现相同的效果,而不必担心 mallocfree

关于c - IP 地址 char* 变量在循环从 ifa_addr 收集地址时意外更改,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36368616/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com