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

C语言字符串间字符赋值失败:剥离$格式符时目标字符串无内容问题

现有代码的核心问题

  • 野指针访问:point 指针没有初始化,也没有申请对应的内存空间,直接执行*point++ = *str++属于未定义行为,轻则写入无效内存拿不到结果,重则直接触发程序崩溃。
  • 死循环逻辑:当遍历到$字符时,没有进入*str != '$'的分支,str指针不会向后移动,循环会一直卡在当前位置永远不会退出。
  • 结果无法导出:函数返回值为void,处理后的内容没有任何方式传递给外部调用方使用,自然没法完成赋值操作。
  • 缺少字符串结束符:就算前面的问题都解决,遍历结束后没有给结果字符串追加\0结束标记,得到的不是合法的C语言字符串。

修复方案

推荐采用调用方传入缓冲区的实现方式,更适配Rom代码库的传统风格,避免堆内存分配忘记释放导致的内存泄漏问题,修复后代码示例如下:

// 新增参数buf为调用方传入的缓冲区,buf_len为缓冲区大小
void act_new(const char *format, char *buf, int buf_len)
{
  const char *str;
  char *point;

  str = format;
  point = buf; // point绑定到传入的缓冲区上

  while ( *str != '\0' && (point - buf) < buf_len - 1) { // 避免缓冲区溢出
    if ( *str != '$' ) {
      *point++ = *str++;
      continue;
    }
    // 遇到$符号,跳过$和后面紧跟的一个字符
    str++;
    if (*str != '\0') {
      str++;
    }
  }
  *point = '\0'; // 追加字符串结束符
}

调用方式示例:

char result[64]; // 提前声明缓冲区
act_new("$t does $d", result, sizeof(result));
// 此时result里就是预期的" does "字符串

如果你希望函数直接返回处理后的字符串,也可以修改为堆内存分配的版本,使用的时候记得用完调用free()释放即可:

char* act_new(const char *format)
{
  int len = strlen(format);
  char *buf = malloc(len + 1); // 最坏情况没有$符,长度和原串一致
  if (!buf) {
    return NULL;
  }
  const char *str = format;
  char *point = buf;

  while ( *str != '\0' ) {
    if ( *str != '$' ) {
      *point++ = *str++;
      continue;
    }
    str++;
    if (*str != '\0') {
      str++;
    }
  }
  *point = '\0';
  return buf;
}

调用方式示例:

char *result = act_new("$t does $d");
// 后续使用result
free(result); // 用完必须释放

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 05:54:05