C语言链表遍历异常求助:重复IP计数时ipNext提前为空
链表遍历与IP重复统计问题排查
我现在碰到一个棘手的问题:原本想实现打印链表所有成员,同时统计链表中IP整数的重复出现次数,但在第二次遍历链表检查重复的时候,ipNext突然指向了空,导致之前的遍历循环直接提前终止了。下面是我写的相关代码,麻烦帮忙找找问题所在?
插入数据函数
void insertIP(bstNode *head, char user[], int ip){ if(head != NULL){ bstNode* startList = head; while ((startList) && (strcmp(startList->data, user) != 0) ){ if(strcmp(user, startList->data)<0) { startList=startList->left; } else if(strcmp(user, startList->data)>0) { startList=startList->left; } } if (startList != NULL){ IP* new = (IP*)malloc(sizeof(IP)); new->ip = ip; //new->count = (new->count + 1); new->ipNext=NULL; IP* temp = startList->ipHead; startList->ipHead = new; new->ipNext = temp; } } }
迭代搜索与统计函数
bstNode* search(char* key, bstNode* root) { int res; bstNode *leaf = root; if( leaf != NULL ) { res = strcmp(key, leaf->data); if( res < 0) search( key, leaf->left); else if( res > 0) search( key, leaf->right); else { printf("\n'%s' found!\n", key); //int count = 0; bstNode *temp = leaf; while (temp->ipHead != NULL) { int tempip = temp->ipHead->ip; int ipcount = 0; uint32_t ip = tempip; struct in_addr ip_addr; ip_addr.s_addr = ip; bstNode *cpy = leaf; ipcount = count(&cpy, tempip); //temp = leaf; printf("The IP address is %s\n C:%d\n", inet_ntoa(ip_addr), ipcount); temp->ipHead = temp->ipHead->ipNext; // 推测你原本要写的遍历逻辑 } } } }
问题分析与修复建议
我帮你梳理下代码里的几个关键问题:
BST遍历逻辑错误(插入函数)
在插入函数的BST节点查找循环中,当strcmp(user, startList->data)>0时,你错误地让startList指向了left子节点——这完全违背了二叉搜索树的规则:大于当前节点值的元素应该去右子树查找。这个错误会导致你根本找不到正确的用户节点,IP链表的插入逻辑自然会紊乱。
修复方法:把这行代码改成startList=startList->right;IP链表遍历指针错误(搜索函数)
你用bstNode *temp = leaf;后直接操作temp->ipHead,这会直接修改原始节点的ipHead指针!遍历一轮后,leaf->ipHead会被移到链表末尾甚至变成空指针,后续遍历自然提前终止。
修复方法:用临时的IP*指针遍历IP链表,不改动原始头指针:IP* ipTemp = leaf->ipHead; // 保存IP链表头节点 while (ipTemp != NULL) { int tempip = ipTemp->ip; // ... 其他统计逻辑 ipTemp = ipTemp->ipNext; // 移动临时指针,不影响原始链表 }count函数的潜在风险
你调用的count(&cpy, tempip)如果内部没有用临时指针遍历,而是直接修改了传入的cpy的ipHead,也会破坏原始链表。确保count函数用临时指针统计:int count(bstNode** node, int targetIp) { int count = 0; IP* temp = (*node)->ipHead; while (temp != NULL) { if (temp->ip == targetIp) { count++; } temp = temp->ipNext; } return count; }
先把这几个问题修复,应该就能解决遍历提前终止的问题啦!
内容的提问来源于stack exchange,提问作者Anon_Singh
相关产品推荐
相关产品推荐

