Hackerrank Post Transition(C语言)代码运行段错误原因排查
错误原因定位
1. 核心崩溃原因:find_town函数逻辑错误
你实现的find_town函数中break语句位置错误,无论是否匹配到目标城镇,第一次循环就会直接退出。如果要查找的城镇不是数组中的第一个元素,town_index会保持初始值-1,最终返回&towns[-1]这个非法内存指针,后续在send_all_acceptable_packages中访问该指针的offices成员时直接触发段错误,和你给出的报错栈完全吻合。
修正后的find_town函数参考:
town* find_town(town* towns, int towns_count, char* name) { for(int i=0; i<towns_count; i++) { if(strcmp(name, towns[i].name) == 0) { return &towns[i]; } } // 题目保证输入的城镇名合法,不会走到该分支 return NULL; }
2. 次要逻辑错误:send_all_acceptable_packages函数存在多处缺陷
- 提前缓存的
src_pk_count是初始包裹数,循环过程中包裹被移走后数量会减少,继续用初始值作为循环上限会导致越界访问 - 目标包裹计数
trg_pk_count仅初始化一次,新增包裹后没有更新,后续新增包裹会覆盖之前写入的内容 - 移动源邮局剩余包裹时,
realloc操作放在了内层循环里,每移动一个元素就执行一次缩容,完全不必要且容易触发内存错误 - 移走当前下标
i的包裹后没有对i做减一操作,会跳过下一个待检查的包裹 - 代码缺少
<stdio.h>头文件引入,部分编译器会编译失败或者出现未定义函数警告
修正后的send_all_acceptable_packages函数参考:
void send_all_acceptable_packages(town* source, int source_office_index, town* target, int target_office_index) { post_office *src_off = &source->offices[source_office_index]; post_office *trg_off = &target->offices[target_office_index]; int min_w = trg_off->min_weight; int max_w = trg_off->max_weight; for(int i=0; i < src_off->packages_count; i++) { if (src_off->packages[i].weight >= min_w && src_off->packages[i].weight <= max_w) { // 目标侧新增包裹 trg_off->packages = realloc(trg_off->packages, sizeof(package) * (trg_off->packages_count + 1)); trg_off->packages[trg_off->packages_count] = src_off->packages[i]; trg_off->packages_count++; // 源侧移动后续元素覆盖被移走的包裹 for(int x = i; x < src_off->packages_count - 1; x++) { src_off->packages[x] = src_off->packages[x+1]; } src_off->packages_count--; // 统一执行一次缩容 src_off->packages = realloc(src_off->packages, sizeof(package) * src_off->packages_count); // 回退下标,避免跳过下一个待检查的包裹 i--; } } }
内容的提问来源于stack exchange,提问作者Omar Essam
相关产品推荐
相关产品推荐

