You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

自定义仿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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 08:06:20