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

Arduino低内存环境下不使用String类的char字符串拼接方法咨询

原代码问题说明

原代码存在两个不可运行的底层问题:

  1. char *aa = "2" 指向的是只读的字符串常量区,strcat 向该地址写入会直接触发内存访问错误
  2. aa 指向的内存空间仅能容纳2个字符(字符'2' + 结束符'\0'),没有多余空间存储拼接后的内容

以下是适配2kB内存Arduino设备、无需使用String类的可行方案,全部采用栈/静态内存,无堆碎片风险:


方案1:静态缓冲拼接函数(最适合单线程Arduino场景,可直接当参数传入)

Arduino为单线程运行,不存在重入冲突,用固定大小的静态缓冲做拼接,内存占用固定,用完不需要手动释放:

// 缓冲大小根据实际需要拼接的最大字符串总长度调整,不要超过内存上限
#define CONCAT_BUF_SIZE 32

char* str_concat(const char* str1, const char* str2) {
  static char buf[CONCAT_BUF_SIZE];
  // 清空缓冲避免旧数据干扰
  memset(buf, 0, CONCAT_BUF_SIZE);
  int len1 = strlen(str1);
  int len2 = strlen(str2);
  // 防止缓冲溢出,超过长度自动截断
  if (len1 + len2 >= CONCAT_BUF_SIZE) {
    len2 = CONCAT_BUF_SIZE - len1 - 1;
  }
  memcpy(buf, str1, len1);
  memcpy(buf + len1, str2, len2);
  buf[len1 + len2] = '\0';
  return buf;
}

// 你的原有业务函数
void abca(char *a)
{
  Serial.println(a);
}

void setup()
{
  Serial.begin(9600);
  char *bb = "1";
  char *aa = "2";
  // 直接传入拼接结果即可
  abca(str_concat(aa, bb));
}

注意:该方案的静态缓冲每次调用会被覆盖,如果你需要同时留存多份拼接结果,不要使用该方案。


方案2:调用方预分配缓冲(无重入问题,最安全)

如果有多个拼接结果需要同时留存,或怕静态缓冲被覆盖,由调用方提前在栈上分配足够空间传入即可,内存自动回收:

char* str_concat(char* dst_buf, const char* str1, const char* str2, int buf_size) {
  memset(dst_buf, 0, buf_size);
  int len1 = strlen(str1);
  int len2 = strlen(str2);
  if (len1 + len2 >= buf_size) {
    len2 = buf_size - len1 - 1;
  }
  memcpy(dst_buf, str1, len1);
  memcpy(dst_buf + len1, str2, len2);
  dst_buf[len1 + len2] = '\0';
  return dst_buf;
}

void abca(char *a)
{
  Serial.println(a);
}

void setup()
{
  Serial.begin(9600);
  char *bb = "1";
  char *aa = "2";
  // 栈上分配刚好够用的缓冲,总长度+1(结束符)即可
  char concat_buf[32];
  abca(str_concat(concat_buf, aa, bb, sizeof(concat_buf)));
}

方案3:C99复合字面量简化写法(不需要单独定义拼接函数)

Arduino的GCC编译器支持C99标准,可以直接用复合字面量在调用时一次性分配栈缓冲,写法更简洁:

void abca(char *a)
{
  Serial.println(a);
}

void setup()
{
  Serial.begin(9600);
  char *bb = "1";
  char *aa = "2";
  // 32为缓冲大小,根据实际需求调整即可
  abca(strcat(strcpy((char[32]){}, aa), bb));
}

通用注意事项

  • 所有方案中的缓冲大小请根据实际拼接的字符串最大总长度调整,不要设置过大浪费内存,也不要过小导致字符串被截断
  • 不要在2kB级小内存设备上使用malloc/free动态分配拼接内存,极易产生堆碎片,最终导致内存不足崩溃

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 18:36:00