自定义mystrlen触发Segmentation fault 11,如何修复匹配标准strlen?
修复自定义strlen实现的问题并对齐标准库功能
你的代码存在三个核心问题,直接导致了段错误和长度计算错误,以下是问题分析和修正方案:
问题点
- 终止条件错误:
mystrlen的循环判断用了str[i] != '\n',但C字符串的结束标志是空字符'\0',不是换行符。这会让函数持续读取内存直到碰到换行符,甚至越界访问非法内存,触发段错误;如果没碰到换行,就会读到内存中随机位置的'\0',返回错误长度(比如你输入"aka"时得到的104)。 gets函数的安全隐患:gets是已废弃的危险函数,它不检查输入长度,当输入超过input数组的100字节时,会直接溢出缓冲区,破坏栈结构,触发段错误。- 返回类型不匹配:标准库
strlen的返回类型是size_t(无符号整数类型),不是int,虽然这不是当前段错误的直接原因,但要对齐标准功能必须修正。
修正后的完整代码
#include <stdio.h> #include <stddef.h> // 引入size_t类型的定义 size_t mystrlen(const char* str) { size_t i = 0; // 正确判断C字符串的结束标志:空字符'\0' while (str[i] != '\0') { i++; } return i; } int main(void) { char input[100]; // 用安全的fgets替代gets,限制读取长度为数组大小(自动留位置存'\0') if (fgets(input, sizeof(input), stdin) != NULL) { // 处理fgets读取到的换行符:标准strlen不会将换行符计入长度 char* newline = input; while (*newline != '\0' && *newline != '\n') { newline++; } if (*newline == '\n') { *newline = '\0'; } // 用%zu作为size_t类型的格式化输出符 printf("The length of your string : %zu\n", mystrlen(input)); } return 0; }
修正细节说明
- 对齐标准
strlen的类型定义:将mystrlen的返回类型和循环变量都改为size_t,符合标准库的设计。 - 修正字符串终止判断:循环条件改为检查
str[i] != '\0',这是C字符串的正确终止逻辑。 - 替换不安全的
gets:用fgets读取输入,指定最大读取长度为数组大小,彻底避免缓冲区溢出。 - 处理换行符:
fgets会把用户输入的回车键('\n')存入数组,手动将其替换为'\0',保证长度计算和标准strlen一致。 - 正确格式化输出:用
%zu作为size_t类型的输出格式符,符合C标准规范。
内容的提问来源于stack exchange,提问作者XYJ
相关产品推荐
相关产品推荐

