添加自定义sortAlphabetically排序函数后loadData函数执行异常的技术求助
首先明确一点:C是同步执行的编程语言,代码会严格按照从上到下的顺序依次执行——loadData会完全执行完毕之后,才会调用sortAlphabetically,根本不需要像JS那样做异步等待,这完全是两个不同运行环境的逻辑,你的疑问方向错了。
真正的问题出在你写的sortAlphabetically函数里,它的逻辑错误和内存操作问题破坏了程序的内存结构(比如堆内存、栈内存),导致前面的loadData函数执行时出现异常(内存破坏的影响是“连锁”的,哪怕代码顺序是先执行loadData,但内存被破坏后,后续的内存操作、函数调用都会出问题,甚至表现为前面的函数运行异常)。
你的排序函数具体有哪些问题?
插入排序逻辑完全错误
你试图实现插入排序,但内层while循环的条件和操作逻辑都不对:- 条件
j > 0 && comparatore的问题:comparatore是strcmp的返回值,只有当它大于0时(表示前面的元素比当前元素大),才需要往后移动元素。你直接判断comparatore非零,会导致前面元素更小时也进入循环,完全违背插入排序的逻辑。 - 循环内的操作错误:你在每次移动元素后立刻把
copy放到j+1的位置,这会导致元素被重复覆盖,数组数据彻底混乱。 - 没有处理
j=0的情况:当i=1时,j=0,此时j>0不成立,内层循环完全跳过,第一个元素根本不会参与排序。
- 条件
不必要的动态内存分配
你用malloc分配了copy指针,但全程只用来存单个RecordSoggetto,完全可以直接在栈上声明变量(RecordSoggetto copy;),既避免内存泄漏,又更高效。调试输出缺少换行
你排序函数里的printf("start sorting");没有加换行符,stdout默认是行缓冲,这会导致输出不会立刻显示,可能让你误以为函数没执行,但这不是核心问题。
修复后的排序函数示例
void sortAlphabetically(RecordSoggetto *elementList, int nElements) { printf("start sorting\n"); int i, j; // 直接在栈上分配临时变量,避免malloc/free和内存泄漏 RecordSoggetto copy; for (i = 1; i < nElements; i++) { // 复制当前待排序元素到临时变量 memcpy(©, &elementList[i], sizeof(RecordSoggetto)); j = i - 1; // 往前遍历,找到合适的插入位置:比copy大的元素往后移 while (j >= 0) { int cmp = strcmp(elementList[j].surname, copy.surname); // 姓氏相同则比较名字 if (cmp == 0) { cmp = strcmp(elementList[j].name, copy.name); } // 只有当前面的元素比copy大时,才需要移动 if (cmp > 0) { memcpy(&elementList[j + 1], &elementList[j], sizeof(RecordSoggetto)); j--; } else { // 找到合适位置,退出循环 break; } } // 将临时变量插入到正确位置 memcpy(&elementList[j + 1], ©, sizeof(RecordSoggetto)); } }
额外的小建议
你loadData里的调试printf也最好加上换行符,比如printf("file opened\n");,否则输出会被缓冲,看起来像是没执行到这一步,容易误导你判断问题位置。
总结
你的程序异常和异步毫无关系,完全是排序函数的逻辑错误导致内存结构被破坏,进而影响了整个程序的运行。修复排序函数的逻辑后,问题应该就能解决。
内容的提问来源于stack exchange,提问作者Pepe

