使用指针更改全局变量值

时间:2014-01-09 08:13:10

标签: c pointers struct global-variables assign

我的代码有问题。我的全局变量没有改变。我已将其地址分配给指针。这是我的struct初始化:

    struct PortData {
        int port;
        int sent;
        int received;
        int total;
        struct PortData *Next;
    };

    struct IPData {
        time_t timestamp;
        uint32_t ip;
        struct PortData Record;
    };

这是我的函数,它返回了地址:

    inline struct IPData *FindIp(uint32_t ipaddr) {
    unsigned int counter;

    for (counter = 0; counter < IpCount; counter++)
        if (IpTable[counter].ip == ipaddr)
            return (&IpTable[counter]);

    if (IpCount >= IP_NUM) {
        syslog(LOG_ERR, "IP_NUM is too low, dropping ip....");
        return (NULL);
    }

    memset(&IpTable[IpCount], 0, sizeof (struct IPData));
    IpTable[IpCount].ip = ipaddr;
    return (&IpTable[IpCount++]); 
    }

此处指针分配给IpTable的地址:

    struct IPData *ptrIPData;
    for (Count = 0; Count < SubnetCount; Count++) {
        if (SubnetTable[Count].ip == (iph->saddr & SubnetTable[Count].mask)) {
            ptrIPData = FindIp(iph->saddr);
            Credit(&(ptrIPData->Record), iph, tcph, srcip);          
        }    
        if (SubnetTable[Count].ip == (iph->daddr & SubnetTable[Count].mask)) {
            ptrIPData = FindIp(iph->daddr);
            Credit(&(ptrIPData->Record), iph, tcph, dstip);
        }

    }

这是我的Credit()函数:

inline void Credit(struct PortData *pordt, struct iphdr *iph, struct tcphdr *tcph, struct in_addr sipaddr) {

    unsigned int sport, dport;

    memset(&source, 0, sizeof (source));
    source.sin_addr.s_addr = iph->saddr; //init source ip
    sport = ntohs(tcph->source);

    memset(&dest, 0, sizeof (dest));
    dest.sin_addr.s_addr = iph->daddr; //init dest ip
    dport = ntohs(tcph->dest);

    packet_size = ntohs(iph->tot_len);
    if (iph->protocol == 6) //6 is protocol TCP
    {
        prev = portdt;
        int sameport = 0;
        while (prev != NULL) {
            if (dport == prev->port || sport == prev->port) {
                if (dport == prev->port) {
                    prev->sent += packet_size;
                }
                if (sport == prev->port) {
                    prev->received += packet_size;
                }
                sameport = 1;
                break;
            }            
        }

        if (sameport == 0) {
            printf("create new node\n");
            newnode = (struct PortData*) malloc(sizeof (struct PortData));
            newnode->received = 0;
            newnode->sent = 0;
            if (sipaddr.s_addr == source.sin_addr.s_addr) {
                if (tcph->syn == 1 || tcph->ack == 1) {
                    newnode->port = dport;
                    newnode->sent = packet_size;
                }
            }
            if (sipaddr.s_addr == dest.sin_addr.s_addr) {
                if (tcph->syn == 1 && tcph->ack == 1) {
                    newnode->port = sport;
                    newnode->received = packet_size;
                }
            }
            newnode->Next = portdt;
            portdt = newnode;
        }//==end-sameport==
    }//iph->protocol//

    prev = portdt;
    while (prev != NULL) {
        fprintf(logfile, "ip = %s port=%d sent=%d bytes received=%d bytes\n", inet_ntoa(sipaddr), prev->port, prev->sent, prev->received);
        prev = prev->Next;
    }
}

我假设在执行Credit()函数后,Iptable[Counter].Record的值必须更改,因为ptrIPData指向了它的地址。但为什么不呢?

2 个答案:

答案 0 :(得分:2)

您正尝试在链接列表Record中插入新项目。您尝试通过编写:

来执行此操作
newnode = (struct PortData*) malloc(sizeof (struct PortData));
// initialise newnode
newnode->Next = portdt;
portdt = newnode;

问题是portdt是局部变量,它包含Record结构的IPData成员的地址。因此,分配给局部变量portdt不会在函数外部显示任何内容。

您需要进行一些更改。首先,您需要将struct PortData Record更改为struct PortData *Record。这是列表的头指针,它必须声明为指向节点的指针,而不是像节点值那样。

然后您仍将&Record传递给Credit,但现在portdt的类型为struct PortData **Record。因此节点插入分配变为

newnode = malloc(sizeof (struct PortData));
// initialise newnode
newnode->Next = *portdt;
*portdt = newnode;

您的代码还有其他问题。我不会尝试将它们全部列出,但这就是我所看到的:

  • 请勿转换malloc
  • 的返回值
  • 您应该检查malloc的错误返回值。
  • prev声明为本地变量,而不是当前看似的全局变量。

答案 1 :(得分:0)

而不是portdt = newnode;,您应该将行替换为:

portdt->port = newnode->port;
portdt->sent = newnode->sent;
portdt->received = newnode->received;
portdt->total = newnode->total;
portdt->Next = newnode->Next;

就像@David所说,portdt = newnode;只是改变局部变量,而不是改变portdt指向的东西。