C语言中链表无法通过函数更新的指针问题求助
嘿,我帮你梳理下这个链表更新的问题,看起来有几个关键的小bug导致你的链表没按预期工作,咱们一个个来解决:
1. 主函数里的upd指针未初始化,引发野指针问题
你在main里声明了bswabe_upd_t* upd;但没给它赋值为NULL,第一次调用bswabe_update_key的时候,*upd是个随机的野指针,这直接导致函数里的链表遍历逻辑彻底乱掉——相当于你从一个非法的内存地址开始找链表节点,不出错都算运气好。
修复方案:
给主函数里的指针加上初始化:
bswabe_upd_t* upd = NULL;
2. 链表遍历逻辑未定位到最后一个节点
你写的遍历循环:
while ( current_node != NULL && current_node->next != NULL) { current_node = current_node->next; current_version++; }
这个循环会在current_node是倒数第二个节点的时候就停下来,因为此时current_node->next是NULL,循环条件不满足了。虽然最后还是能把新节点挂到链表末尾,但逻辑上很别扭,而且你里面的current_version变量其实根本没用到,完全可以删掉简化代码。
优化后的遍历逻辑:
bswabe_upd_t *current_node = *upd; // 一路走到链表的最后一个节点 while (current_node != NULL && current_node->next != NULL) { current_node = current_node->next; }
这样结束后current_node就精准指向最后一个节点(如果链表非空的话)。
3. u_cp的群类型初始化错误
看你的结构体注释,u_cp应该是Zr群的元素,但你用了element_init_G1来初始化它——这会把它变成G1群的元素。后续调用element_invert的时候,操作的对象类型不匹配,这也是你输出显示字母O(PBC库对G1元素的默认输出格式)的原因,根本不是你想要的Zr元素值。
修复方案:
把初始化改成Zr对应的函数:
element_init_Zr(new_node->u_cp, pub->p);
4. 遗漏临时元素清理,存在内存泄漏风险
你在函数里初始化了beta这个元素,但没调用element_clear释放它,长期运行会累积内存泄漏,顺手加上就好。
修复后的完整函数代码
void bswabe_update_key(bswabe_msk_t** msk, bswabe_pub_t* pub, bswabe_upd_t** upd) { element_t beta; /* 分配新节点并初始化 */ bswabe_upd_t* new_node = malloc(sizeof(bswabe_upd_t)); element_init_Zr(beta, pub->p); // 修正u_cp的群类型初始化 element_init_Zr(new_node->u_cp, pub->p); bswabe_upd_t *current_node = *upd; element_random(beta); /* 遍历到链表末尾 */ while (current_node != NULL && current_node->next != NULL) { current_node = current_node->next; } /* 设置新节点的版本号 */ new_node->u_msk_s = current_node == NULL ? 1 : current_node->u_msk_s + 1; /* 计算u_cp的值 */ element_invert(new_node->u_cp, (*msk)->beta); element_printf("Version %d: %B\n", new_node->u_msk_s, new_node->u_cp); /* 将新节点加入链表 */ new_node->next = NULL; if (current_node != NULL) current_node->next = new_node; else *upd = new_node; /* 清理临时元素 */ element_clear(beta); }
主函数的补充修复
除了初始化upd,最后还要记得清理链表和其他资源,避免内存泄漏:
int main(){ bswabe_pub_t* pub; bswabe_msk_t* msk; // 初始化upd为NULL,杜绝野指针 bswabe_upd_t* upd = NULL; parse_args(argc, argv); bswabe_setup(&pub, &msk); // 多次调用更新函数 for(int i=0; i<6; i++){ bswabe_update_key( &msk, pub, &upd); } // 清理链表资源 bswabe_upd_t* temp; while (upd != NULL) { temp = upd; upd = upd->next; element_clear(temp->u_cp); free(temp); } // 清理pub和msk(根据bswabe的实现来,确保有对应的释放函数) bswabe_free_pub(pub); bswabe_free_msk(msk); return 0; }
这样改完之后,你的链表应该就能正常按版本号递增更新,u_cp的计算也会符合预期,输出的内容也会是正确的Zr群元素值啦。
内容的提问来源于stack exchange,提问作者Luigi2405

