You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ft_substr函数传入负整数start参数引发段错误的求助

ft_substr传入负数start参数导致段错误的修复方案

问题代码

char    *ft_substr(char const *s, unsigned int start, size_t len)
{
    char    *substr;

    if (!s)
        return (NULL);
    if (start > ft_strlen(s))
        len = 0;
    if (start <= ft_strlen(s) && s[start] != '\0')
    {   
        if (ft_strlen(s + start) < len)
            len = ft_strlen(s + start);
    }
    substr = (char *)malloc(sizeof(*s) * (len + 1));
    if (!substr)
        return (NULL);
    if (len == 0)
        return (substr);
    ft_strlcpy(substr, s + start, len + 1); 
    return (substr);
}

注:ft_strlen等为自定义实现的对应标准库函数。

问题分析

传入-1作为start参数时,会被隐式转换为32位无符号整数4294967295。虽然代码里有start > ft_strlen(s)的判断会把len设为0,但第二个if的条件start <= ft_strlen(s) && s[start] != '\0'可能被编译器优化,导致s[start]被提前访问——即使start <= ft_strlen(s)不成立,也会触发非法内存访问,从而在Ubuntu 22.04上引发段错误(Mac上编译器优化策略不同,未触发该问题)。

另外,原代码未处理start等于字符串长度的情况,此时s[start]是'\0',子串应为空,但原代码可能保留原len值,存在潜在风险。

修复后的代码

char    *ft_substr(char const *s, unsigned int start, size_t len)
{
    char    *substr;
    size_t  s_len;

    if (!s)
        return (NULL);
    s_len = ft_strlen(s);
    // 覆盖start等于或超过字符串长度的所有情况(包括超大无符号数)
    if (start >= s_len)
        len = 0;
    else if (s[start] != '\0')
    {   
        if (ft_strlen(s + start) < len)
            len = ft_strlen(s + start);
    }
    substr = (char *)malloc(sizeof(*s) * (len + 1));
    if (!substr)
        return (NULL);
    if (len == 0)
    {
        *substr = '\0'; // 显式初始化空字符串,避免返回未初始化内存
        return (substr);
    }
    ft_strlcpy(substr, s + start, len + 1); 
    return (substr);
}

修复要点

  1. 提前计算并缓存字符串长度s_len,避免重复调用ft_strlen,同时确保判断逻辑的一致性。
  2. 将start > s_len改为start >= s_len,覆盖start刚好等于字符串长度的场景,统一将len设为0。
  3. 用else if替代原有的独立if,确保只有当start < s_len时才会访问s[start],彻底避免非法内存访问。
  4. 当len为0时,显式将返回的指针指向的内存初始化为'\0',保证返回的是空字符串而非未初始化内存,符合预期行为。

这样修改后,无论传入多大的无符号start值,都不会触发非法内存访问,在Ubuntu和Mac上均可稳定运行。

内容的提问来源于stack exchange,提问作者user21073092

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 07:45:36