C 在不修改内容的情况下传递字符串数组

C 在不修改内容的情况下传递字符串数组,c,arrays,C,Arrays,我一直在尝试将字符串数组传递给一个函数,该函数可以查找主机的所有IP地址。我的问题是,在我用地址填充数组后,内容立即意外更改。将字符串分配给数组的一部分后,我立即打印数组的内容,这就是我如何知道我正在初始化数组的原因。然后在循环完成后,我尝试访问数组中的所有地址,所有值都更改为上次传入数组的值。为什么会这样?我做错了什么? 以下是函数: static int getHostIP(char*ip_list[]) { char hostName[80]; if(gethostnam

我一直在尝试将字符串数组传递给一个函数,该函数可以查找主机的所有IP地址。我的问题是,在我用地址填充数组后,内容立即意外更改。将字符串分配给数组的一部分后,我立即打印数组的内容,这就是我如何知道我正在初始化数组的原因。然后在循环完成后,我尝试访问数组中的所有地址,所有值都更改为上次传入数组的值。为什么会这样?我做错了什么? 以下是函数:

static int getHostIP(char*ip_list[])
{
    char hostName[80];

    if(gethostname(hostName, sizeof(hostName)) == SOCKET_ERROR)
    {
        printf("Error %s when getting host name.\n", WSAGetLastError());
        return 1;
    }
    printf("Hostname: %s\n", hostName);
    struct addrinfo *result = NULL;

    if(getaddrinfo(hostName,NULL, NULL, &result) == 1)
    {
        printf("Error %s when getting host address info.\n", WSAGetLastError());
        return 1;
    }

    //iterate over IP addresses
    struct addrinfo *ptr;

    int x = 0;
    for(x = 0,ptr = result; ptr != NULL;ptr = ptr->ai_next, x++)
    {
        struct sockaddr_in *hostaddr = (struct sockaddr_in*)ptr->ai_addr;
        char ip_addr[80];
        inet_ntop(ptr->ai_family,(void*)&hostaddr->sin_addr, ip_addr, sizeof(ip_addr));
        ip_list[x] = ip_addr;
    }
    int i;
    for(i = 0; i < 7;i++)
    {
        printf("IP: %s\n", ip_list[i]);
    }
    return 0;
}

您的数据是如何分配的

尝试:

static int getHostIP(char**ip_list)

是否正确初始化传递给此函数的数组。您正在声明一个字符指针数组的输入。在c中传递数组时,还必须传递初始化数组的长度。内存需要存放在某个地方,并由系统保留

请您提供呼叫代码,以便我们了解您的错误


或者---您可以通过byref传递整个数组,这样您就可以得到一个out指针,并且该数组将由该函数声明。因为您不知道可以匹配多少个IP地址,所以这可能是一种更好的设计

您所经历的行为是由变量
ip_addr
引起的,该变量在每次迭代期间始终指向堆栈中的同一缓冲区。因此,
ip_list
中的所有指针都指向同一个缓冲区,该缓冲区包含在循环的最后一次迭代中计算的值

如果使用
malloc
在堆中分配此缓冲区,则问题应该得到解决,因为现在循环块将为每个ip创建一个新的缓冲区。例如:

    #define BUFFER_SIZE 80 // no in the function body 
    char * ip_addr = NULL;

    for(x = 0,ptr = result; ptr != NULL;ptr = ptr->ai_next, x++)
    {   
        ip_addr = malloc(BUFFER_SIZE);
        struct sockaddr_in *hostaddr = (struct sockaddr_in*)ptr->ai_addr;
        inet_ntop(ptr->ai_family,(void*)&hostaddr->sin_addr, ip_addr, BUFFER_SIZE);
        ip_list[x] = ip_addr;
    }

我使用这个char*ip_列表[80]={0}分配我的数据;在主体功能上;我假设这应该是一个char*ip_addr=NULL;是的,对不起,我刚刚写下了我的答案。我没有试过。仍在处理中。现在我遇到了另一个问题,列表只存储IP地址的前4个字符,其余的似乎丢失了。出现了另一个错误。问题是传递到inet_ntop函数的缓冲区大小。更新我的答案。哦,我明白了,因为我们没有声明数组的大小,sizeof函数为缓冲区大小提供了一些随机数。现在可以用了,谢谢。
    #define BUFFER_SIZE 80 // no in the function body 
    char * ip_addr = NULL;

    for(x = 0,ptr = result; ptr != NULL;ptr = ptr->ai_next, x++)
    {   
        ip_addr = malloc(BUFFER_SIZE);
        struct sockaddr_in *hostaddr = (struct sockaddr_in*)ptr->ai_addr;
        inet_ntop(ptr->ai_family,(void*)&hostaddr->sin_addr, ip_addr, BUFFER_SIZE);
        ip_list[x] = ip_addr;
    }