我实现的C语言strncmp函数是否正确?请帮忙排查问题
自定义strncmp实现的缺陷分析
以下是你提供的自定义my_strncmp实现及测试代码:
/* * IT IS ENOUGH TO CHECK IF WE REACHED THE LENGTH OF ONE * OF THE STRINGS! :) */ int my_strncmp(char *s1, char *s2, unsigned int n) { unsigned int i; i = 0; while ((s1[i] == s2[i]) && (s1[i] != 0) && (i < n)) i++; return (s1[i] - s2[i]); } #include <stdio.h> #include <string.h> int main(void) { char *str1 = "Hello"; char *barrier = "XXXXXX"; char *str2 = "Hellz"; int n = -1; int max_len = 0; int res; max_len = strlen(str1); if (strlen(str1) < strlen(str2)) max_len = strlen(str2); // making sure that n is tested way beyond the strlen of strings max_len += 2; while (n < max_len) { res = strncmp(str1, str2, n); printf(" strncmp(\"%s\",\"%s\", %d) = %d\n", \ str1, str2, n, res); res = my_strncmp(str1, str2, n); printf("my_strncmp(\"%s\",\"%s\", %d) = %d\n\n", \ str1, str2, n, res); n++; } return (0); }
存在的缺陷与错误
参数类型不符合标准
原生strncmp的参数为const char *s1, const char *s2,因为函数不会修改输入字符串。你的实现使用char *,当传入字符串字面量(如测试中的"Hello")这类const数据时,编译器会抛出警告,也违背了函数的设计契约。n=0时行为错误
根据C标准,当n=0时,strncmp应直接返回0(因为不需要比较任何字符)。但你的实现中,当n=0时,循环条件i < n不成立,直接返回s1[0] - s2[0],这与原生函数的行为完全不符。字符比较未按无符号处理
C标准规定,strncmp会将每个字符转换为unsigned char后再进行比较。你的实现直接用char类型相减,若遇到带符号的char(比如值为0xFF的字符,在带符号char中是-1),会导致比较结果与原生函数相反。例如s1字符为0xFF、s2为0x00时,原生strncmp返回255,而你的实现返回-1。测试用例存在未定义行为
测试中n初始值为-1,而n在my_strncmp中是unsigned int类型,-1会被转换为UINT_MAX(极大的无符号数)。此时函数会访问字符串末尾之后的内存(即使有barrier),这属于未定义行为,可能导致程序崩溃或不可预期的结果。
内容的提问来源于stack exchange,提问作者Atti
相关产品推荐
相关产品推荐

