自定义仿strcmp的xstrcmp函数运行结果异常排查
自定义xstrcmp函数运行异常问题排查
问题复现代码
#include <stdio.h> #include <string.h> int main() { char str1[20],str2[20]; gets(str1); gets(str2); printf("\n%d",xstrcmp(str1,str2)); return 0; } int xstrcmp(char *p1,char *p2){ int k; while(*p1!='\0'||*p2!='\0'){ if((*p1-*p2)==0){ p1++,p2++; continue; } else{ k= ((*p1)-(*p2)); } } return k; }
存在的问题
- 核心逻辑死循环:当两个指针指向的字符不相等时,代码仅计算了字符差值赋值给
k,既没有移动指针,也没有跳出循环,while循环的判断条件会一直成立,程序会无限卡在else分支重复执行,永远走不到返回结果的步骤。 - 返回值未初始化风险:如果输入的两个字符串完全相等,整个循环过程中不会进入else分支给
k赋值,k作为栈上的局部变量存储的是随机垃圾值,就算循环正常结束,返回结果也完全不可控。 - 函数隐式声明隐患:
xstrcmp的定义写在main函数之后,调用前没有做前置声明,C89标准会对未声明的函数做隐式声明(默认返回值为int),虽然编译可能不报错,但如果后续修改函数返回值类型,会触发难以排查的未定义行为。 - 废弃API风险:代码使用了已经被C标准完全移除的
gets()函数,该函数不做输入长度校验,只要输入长度超过字符数组容量就会触发缓冲区溢出,属于高危安全隐患。
修复后参考实现
#include <stdio.h> #include <string.h> // 前置函数声明 int xstrcmp(char *p1, char *p2); int main() { char str1[20], str2[20]; // 替换废弃的gets,限制最大读入长度避免溢出 fgets(str1, sizeof(str1), stdin); fgets(str2, sizeof(str2), stdin); // 清除fgets读入的行尾换行符 str1[strcspn(str1, "\n")] = '\0'; str2[strcspn(str2, "\n")] = '\0'; printf("\n%d", xstrcmp(str1, str2)); return 0; } int xstrcmp(char *p1, char *p2) { // 字符相等且两个字符串都没到末尾时,同步移动指针 while (*p1 && *p2 && *p1 == *p2) { p1++; p2++; } // 遇到不等字符/任意字符串到末尾时,直接返回字符差值,和标准strcmp逻辑对齐 return *p1 - *p2; }
内容的提问来源于stack exchange,提问作者Divyansh
相关产品推荐
相关产品推荐

