C语言截取子串时触发SIGSEGV段错误问题咨询
段错误触发原因
- 缺少入参空指针校验:如果调用时传入的源字符串
cad或目标字符串指针tCad为NULL,代码访问cad[iC]、tCad[iS]时会直接触发非法内存访问,抛出段错误。 - 目标内存空间不足:如果调用者为
tCad分配的内存空间小于fin - ini + 2(子串字符总长度+结尾终止符'\0'的长度),写入时会发生内存越界,触发段错误。 - 源字符串不合法:如果传入的
cad不是以'\0'结尾的合法C字符串,strlen(cad)会越界读取内存,要么返回异常大的长度值导致后续cad[iC]越界访问,要么读取过程中就直接触发段错误。
修复方案
基础修复版(兼容原有函数签名)
新增空指针校验,同时在函数注释中明确调用约束:
/* * 功能:截取cad中从ini到fin下标(闭区间)的子串写入tCad * 调用约束: * 1. cad必须是合法的以'\0'结尾的C字符串 * 2. tCad指向的内存空间必须 >= fin - ini + 2 字节 * 返回值:1表示截取成功,0表示参数非法截取失败 */ int extraercadena(char *cad, char *tCad, int ini, int fin){ int iC, iS; // 新增空指针校验 if (cad == NULL || tCad == NULL) return 0; int cad_len = strlen(cad); if ((ini > fin) || (ini < 0) || (fin >= cad_len)) return 0; iS = 0; for(iC = ini; iC <= fin; iC++){ tCad[iS] = cad[iC]; iS++; } tCad[iS] = '\0'; return 1; }
安全增强版(新增内存长度校验)
新增tCad可用长度入参,从代码层面避免越界写入风险:
/* * 功能:截取cad中从ini到fin下标(闭区间)的子串写入tCad * 参数:tCad_len 传入tCad指向的内存总可用字节数 * 返回值:1表示截取成功,0表示参数非法/内存不足截取失败 */ int extraercadena(char *cad, char *tCad, int ini, int fin, int tCad_len){ int iC, iS; // 新增空指针和可用空间基础校验 if (cad == NULL || tCad == NULL || tCad_len <= 0) return 0; int cad_len = strlen(cad); int sub_str_len = fin - ini + 1; // 新增目标内存空间充足性校验 if ((ini > fin) || (ini < 0) || (fin >= cad_len) || (sub_str_len + 1 > tCad_len)) return 0; iS = 0; for(iC = ini; iC <= fin; iC++){ tCad[iS] = cad[iC]; iS++; } tCad[iS] = '\0'; return 1; }
内容的提问来源于stack exchange,提问作者Mario Gaitan
相关产品推荐
相关产品推荐

