C语言字符串排序程序输入超过3个字符串触发段错误,求原因
段错误触发原因
核心错误:swap函数存在野指针非法内存访问
你在swap函数中定义的char (*t)[c];仅声明了一个指向长度为c的字符数组的指针,没有为其分配实际可用的内存空间,属于未初始化的野指针。执行strcpy(*t, *s)时,直接将字符串拷贝到野指针指向的未知内存地址,属于非法内存访问,这是触发段错误的直接原因。
输入2、3个字符串时未触发报错是典型的C语言未定义行为:小数据量下野指针刚好指向了当前进程有权限访问的空闲栈内存,暂时不会触发系统内存保护信号;当输入字符串数量增加后,要么野指针指向了进程无权访问的内存地址,要么拷贝操作覆盖了栈上的关键数据(比如函数返回地址、栈帧边界标记),就会触发段错误。
潜在风险:输入未做长度校验
get函数中scanf("%s", *(s+i))没有限制输入长度,若用户输入的字符串长度超过30(你定义的单字符串最大长度为31,需留1位存储字符串结束符\0),会发生缓冲区溢出,也可能触发段错误。
修复方案
1. 修复swap函数的野指针问题
将临时指针改为栈上分配的字符数组即可,代码如下:
void swap(int c, char (*s)[c], char (*s1)[c]) { // 栈上分配长度为c的临时数组存储中转字符串 char t[c]; strcpy(t, *s); strcpy(*s, *s1); strcpy(*s1, t); }
2. 优化输入校验
将get函数中的scanf调用修改为长度限制版本,避免缓冲区溢出:
scanf("%30s", *(s+i));
可选优化:优化排序逻辑
你当前的冒泡排序外层循环的i变量没有参与内层循环控制,存在重复比较的冗余操作,可以调整为标准冒泡排序写法提升效率:
void sort(int r, int c, char (*s)[c]) { int i, j; for(i = 0; i < r; i++) { // 内层循环只需比较到未排序的边界 for(j = 0; j < r-i-1; j++) { if(strcmp(*(s+j),*(s+j+1)) > 0) { swap(c, (s+j), (s+j+1)); } } } }
内容的提问来源于stack exchange,提问作者Avinash Kumar Gupta
相关产品推荐
相关产品推荐

