自定义strlcat触发段错误,标准库版本无此问题的原因排查
自定义strlcat实现的段错误与标准库行为解析
你在重实现strlcat时遇到的段错误,以及标准库版本的特殊输出,核心原因集中在数组初始化越界、ft_strlen的缺陷,以及自定义函数的逻辑漏洞上,具体分析如下:
1. 触发段错误的直接原因:数组初始化越界
你的测试代码中:
char s1[5] = "Hello";
字符串"Hello"包含5个可见字符,加上C字符串必需的终止符'\0',总共需要6字节的存储空间,但你只给s1分配了5字节。这会导致初始化时'\0'无法被写入s1,最终s1是一个没有终止符的非法字符串。
当ft_strlen遍历s1时,会一直读取内存直到找到'\0',这会越界访问不属于s1的内存区域,直接触发段错误。
2. ft_strlen的致命缺陷
标准库的strlcat在计算目标字符串长度时,会严格限制读取范围:最多读取size个字符来寻找终止符,不会越界访问。但你的ft_strlen没有任何边界检查,只要输入的字符串没有'\0',就会无限遍历内存,必然触发未定义行为(比如段错误)。
3. 自定义ft_strlcat的其他逻辑漏洞
除了上述问题,你的ft_strlcat还有几个不符合标准的地方:
- 类型不匹配:
d_len和s_len使用int类型,但size是unsigned int,当d_len >= size时,size - d_len -1会因为无符号整数溢出变成一个极大值,导致循环条件错误,可能越界写入。 - 未处理
size <= d_len的场景:当目标字符串长度已经大于等于size时,标准strlcat会直接返回size + s_len且不修改目标字符串,但你的代码仍会尝试写入dest[i + d_len],进一步加剧越界风险。 - 空指针检查顺序错误:你先调用了
ft_strlen(src),再检查src是否为空,若src是空指针,ft_strlen会先触发段错误,检查失去意义。
4. 标准库strlcat输出的解释
标准库strlcat的输出strlcat :: Hello World! :: 12 :: sizeof 5是未定义行为的巧合结果:
- 因为
s1没有终止符,strlcat会读取size(5)个字符作为目标长度(找不到'\0'),然后计算返回值为5 + 7 = 12(" World!"的长度是7)。 - 由于栈内存布局中
s1紧跟s2,printf输出s1时,会一直读取到s2的'\0',所以显示出Hello World!,但这并不是strlcat修改的结果——实际上strlcat因为size <= d_len,没有对s1做任何写入操作。
内容的提问来源于stack exchange,提问作者Emperor_Udan
相关产品推荐
相关产品推荐

