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

Arduino C++中itoa导致strcat无法正常追加内容的问题排查

问题原因
  • 数组内存溢出(越界访问):你定义的outputString用字符串字面量初始化时,数组大小被自动设为7("TOSBC_"共6个字符,加上末尾的终止符'\0')。但后续通过strcat追加的内容(cmdtype、""、"00001212"、"")总长度远大于7,导致写入的数据超出outputString的内存范围,破坏了栈上的其他数据(包括后续定义的outputCheckSumHex或outputString自身内容)。
  • itoa触发问题显现:注释itoa时,虽已内存越界,但未破坏outputString的有效数据;调用itoa时,outputCheckSumHex的内存位置刚好和outputString越界写入的区域重叠,写入十六进制字符串时直接覆盖了之前的内容,最终导致输出异常。
解决方案

方案1:预先分配足够大的char数组

计算最终字符串的最大可能长度,直接定义足够大的数组(预留余量避免后续扩展再次溢出):

char outputString[32] = "TOSBC_"; // 预留足够空间容纳所有追加内容

这样strcat操作就不会出现内存越界问题。

方案2:使用Arduino的String类(更简洁安全)

String类会自动管理内存,无需手动处理数组大小,代码更易维护:

void loop() {
  if (Serial.available() > 0 && canPrint == true) {
    String outputString = "TOSBC_";
    Serial.println(outputString);
    
    outputString += cmdtype;
    Serial.println(outputString);
    outputString += "_";
    Serial.println(outputString);
    outputString += "00001212";
    outputString += "_";
    Serial.println("Line w/ \"00001212\" should be below");
    Serial.println(outputString);

    int outputCheckSum = checkSumGenerator((char*)outputString.c_str());
    char outputCheckSumHex[3];
    itoa(outputCheckSum, outputCheckSumHex, 16);

    Serial.println(outputCheckSum);
    Serial.println(outputCheckSumHex);

    outputString += outputCheckSumHex; // 追加校验和到最终字符串
    Serial.println(outputString);
    canPrint = false;
  }
}

额外优化:修复校验和函数的循环边界

原checkSumGenerator中固定循环i < 21易出错,应根据实际字符串长度遍历:

int checkSumGenerator(char message[]) {
  int checkSum = 0;
  int len = strlen(message);
  for (int i = 0; i < len; ++i)  // 遍历整个有效字符串
  {
    checkSum ^= message[i];
  }
  Serial.println(checkSum);
  Serial.println("Printed checksum.");
  return checkSum;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 11:31:07