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

Arduino Nano执行memcpy时崩溃,求原因分析

Arduino Nano执行memcpy时崩溃的原因分析

问题场景

在Arduino Nano开发中,我们通过decrypt函数解密Base64编码的rxPacket得到字符串decryptedRes,尝试提取最后一个^前的内容时,执行memcpy引发设备崩溃:

基础定义代码

const uint8_t RX_MSG_MAX_LENGTH = 160;
char rxPacket[RX_MSG_MAX_LENGTH];

const char *decrypt(const char *base64Text) {
  // ... 解密逻辑实现
  return (char*) message;
}

const char *decryptedRes = decrypt(rxPacket);

提取逻辑代码

// verify checksum
//char checker[RX_MSG_MAX_LENGTH] = "";
char * checker = new char[strlen(decryptedRes) + 1];

const char * pos = strrchr(decryptedRes, '^');
if (pos != nullptr) {
  uint8_t length = pos - decryptedRes + 1; // 包含分隔符^的长度
  memcpy(checker, decryptedRes, length); // 执行此处时Nano崩溃
  checker[length] = '\0';

  // ... 后续校验逻辑
}

崩溃原因分析

1. 动态内存分配失败(最可能原因)

Arduino Nano搭载的ATmega328P芯片仅拥有2KB SRAM,扣除系统占用后可用内存极为有限:

  • 当剩余内存不足以分配strlen(decryptedRes)+1字节的连续空间时,new会返回空指针(AVR平台下直接触发内存访问错误)。
  • 后续memcpy操作空指针指向的非法内存,直接导致设备崩溃。
  • 此外,AVR平台的动态内存管理易产生内存碎片,即使总剩余内存足够,也可能因碎片无法分配连续空间导致分配失败。

2. decrypt函数返回非法内存

如果decrypt函数内部的message是栈内存(例如char message[RX_MSG_MAX_LENGTH];),函数返回后栈内存会被系统回收复用:

  • 虽然Serial.println(decryptedRes)可能暂时打印出正确内容(栈内存尚未被覆盖),但后续执行strlen、strrchr、memcpy时,栈内存已被其他操作覆盖,访问非法内存引发崩溃。

3. 长度计算溢出风险

length被定义为uint8_t(8位无符号整数,最大值255):

  • 若decryptedRes的长度超过255,pos - decryptedRes + 1的结果会溢出,变成远小于实际值的错误数值。
  • 虽不会直接导致memcpy崩溃,但后续使用checker时会因数据截断引发逻辑错误,间接导致设备异常。

内容的提问来源于stack exchange,提问作者Musa P.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 11:31:02