Arduino调用deserializeJson解析缺失字符串字段时崩溃的解决方案
问题原因
这个崩溃和C++字符串的空终止符机制没有直接关联。
当待解析JSON中不存在目标键时,doc["something"]会返回一个类型为null的JsonVariant实例。将这个null类型的Variant隐式转换为const char*时,得到的不是指向带'\0'结尾的有效字符串的内存地址,而是nullptr(空指针,不指向任何有效内存区域)。Serial.printf的%s格式化占位符要求传入的参数必须是指向合法C字符串的首地址,传入空指针属于未定义行为,在Arduino常用的AVR、ESP系列MCU上会直接触发硬件异常导致设备崩溃。
空终止符机制是合法C字符串的末尾标记,该问题本质是空指针访问,和字符串末尾是否有'\0'无关。
正确规避方案
不需要强制要求上游JSON必须传入对应字段,使用ArduinoJson原生提供的安全访问接口即可避免崩溃:
- 首先增加解析结果校验,避免JSON格式错误、文档容量不足导致的解析失败问题
- 访问字段时做空值判断,或者直接指定字段缺失时的默认值,保证传入
printf的指针永远指向合法字符串
方案1:显式判空(兼容所有ArduinoJson版本)
StaticJsonDocument<800> doc; DeserializationError err = deserializeJson(doc, payload); if (err) { Serial.printf("JSON解析错误: %s\n", err.c_str()); return; } const char* something = nullptr; if (!doc["something"].isNull()) { something = doc["something"].as<const char*>(); } else { // 字段不存在时自定义默认值 something = "未配置"; } Serial.printf("something: %s\n", something);
方案2:用默认值运算符(ArduinoJson 6.0及以上版本支持,写法最简洁)
ArduinoJson 6版本之后支持|运算符直接指定字段缺失、类型不匹配时的兜底值,返回的指针永远指向合法的带空终止符的C字符串:
StaticJsonDocument<800> doc; DeserializationError err = deserializeJson(doc, payload); if (err) { Serial.printf("JSON解析错误: %s\n", err.c_str()); return; } const char* something = doc["something"] | "未配置"; Serial.printf("something: %s\n", something);
内容的提问来源于stack exchange,提问作者JorisVV
相关产品推荐
相关产品推荐

