C如何按值复制?

时间:2015-08-24 11:26:45

标签: c

我正在使用以下函数来解析CIDR表示法并最终返回所有IP地址的数组。

我在这一行遇到了问题:network_addr = last_addr = addr.s_addr;

我需要3个变量来保存网络地址,最后地址和原始地址,因此我可以对它们应用位移运算符。但是,目前它似乎是在addr.s_addr的参考。

如何按值复制?

int parse_ipv4_cidr(char *ip_cidr)
{
    struct in_addr addr;
    int cidr;
    char *token;
    uint32_t netmask, network_addr, last_addr;

    token = strtok(ip_cidr, "/");

    /*
     *  Validate IPV4 CIDR address
     */
    if(!inet_aton(token, &addr) ||
       !(token = strtok(NULL, "/")) ||
       (atoi(token) < 0 || atoi(token) > 32))
    {
        printf("Invalid CIDR notation. Example format: 192.0.0.1/21\n");
        return 1;
    }

    cidr = atoi(token);
    network_addr = last_addr = addr.s_addr;

    /*
     *  Create the netmask
     */
    netmask = 0xFFFFFFFF;
    netmask <<= 32 - cidr;
    netmask = ntohl(netmask);

    /*
     *  Calculate network address
     */
    network_addr = network_addr & netmask;

    /*
     *  Calculate last address
     */
    last_addr = (last_addr & netmask) + ~netmask;

    ...
}

2 个答案:

答案 0 :(得分:2)

我认为您的问题不在于引用/按值复制(您已经按值复制)。在我看来,你似乎搞砸了网络/主机字节顺序。

sa_addr的{​​{1}}字段按网络字节顺序排列;当您将其复制到struct in_addrnetwork_addr时,您应该将其转换为主机字节顺序,因为您将进行转换和其他操作。

此外,由于某种原因,代码假定last_addr处于网络字节顺序,而实际上它是以主机字节顺序。事情并没有加起来。

坚持主机字节顺序,一切都应该有效。

更改此行:

netmask

要:

network_addr = last_addr = addr.s_addr;

并删除此行:

network_addr = last_addr = ntohl(addr.s_addr);

您可能希望最后添加netmask = ntohl(netmask); ,并可能将返回类型更改为return network_addr;

答案 1 :(得分:0)

您可能需要malloc新变量,然后将memcpy旧变量添加到新变量中。