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

指针访问字符串无法回退的问题及代码疑问

C语言指针操作的两个问题及解答

问题描述

  1. 实现ft_between函数时,通过指针自增赋值字符后,指针指向字符串末尾,直接用printf输出无内容,必须偏移16位才能打印。疑惑为何之前类似操作没问题,是否和malloc有关?想找不用数组下标、纯指针操作的“回退”方法。
  2. ft_nbr2str函数中,指针自增后返回调用方却能正常打印整个字符串,对此存在疑问。

相关代码

ft_between函数

char *ft_between(char *str, size_t from, size_t to)
{
    char *between;

    between = malloc(16);

    while ((from >= 0) && (from < to) && (to < ft_strlen(str)))
    {
        *(between++) = str[from++];
    }
    *between = '\0';
    printf("%s\n", between); // 无输出
    printf("%s\n", between - 16); // 能打印,但之前从没这么做过...
    return (between);// 调用方拿到的指针仍指向字符串末尾
}

ft_nbr2str函数

void    ft_nbr2str(char *str, size_t nbr, char *base, size_t base_len)
{
    if (nbr >= base_len)
    {
        ft_nbr2str(str, (nbr / base_len), base, base_len);
        while (*str != '\0')
            str++;
        *str = base[nbr % base_len];
    }
    else
        *str = base[nbr];
}

问题解答

关于ft_between的问题

  • 核心原因:你在循环中直接修改了between指针本身——每次between++都会让它从malloc返回的起始地址向内存高地址移动,循环结束后它已经指向了字符串末尾的'\0'位置,此时用它打印自然是空字符串。
  • 和malloc无关,完全是指针操作逻辑的问题。之前没遇到这种情况,大概率是之前的代码中保留了原始指针的副本,没有直接移动指向堆内存起始位置的指针。
  • 指针“回退”的正确做法:保存malloc返回的原始指针,后续操作使用副本,最终用原始指针打印和返回:
    char *ft_between(char *str, size_t from, size_t to)
    {
        char *between = malloc(16);
        char *start = between; // 保存堆内存的起始地址
    
        // 注意:size_t是无符号类型,from >= 0永远为真,可删除该判断
        while ((from < to) && (to < ft_strlen(str)))
        {
            *(between++) = str[from++];
        }
        *between = '\0';
        printf("%s\n", start); // 用原始起始地址打印
        return start; // 返回起始地址,调用方才能拿到完整字符串
    }
    
  • 为什么偏移16位能打印?因为你malloc了16字节,起始地址刚好是between -16(前提是你写满了16字节),但这属于未定义行为——如果to-from小于16,这个操作会访问到堆内存之外的区域,绝对不能这么用。

关于ft_nbr2str的疑问

这个函数的关键在于C语言的函数参数是值传递:

  • 每次递归调用ft_nbr2str时,传入的str是原始指针的副本,子函数中对str的自增操作只会修改副本,不会改变调用方手里的原始指针。
  • 递归过程中,所有字符都是从原始指针指向的缓冲区起始位置开始写入的,调用方手里的指针始终指向缓冲区开头,所以能正常打印整个字符串。

内容的提问来源于stack exchange,提问作者RoGKôT

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 00:20:31