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

C++中从字符串与变量构建字符数组报错求助

问题分析与解决

核心问题

你代码里的auto mstr = (char*)"";是错误根源:

  1. 字符串字面量""是只读的,且仅占1字节(存储终止符\0),没有空间存放后续拼接的浮点数和换行符,导致sprintf_P写入时缓冲区溢出,触发警告。
  2. 用sprintf_P(mstr, PSTR("%s %f"), mstr, ...)属于未定义行为——同时将目标缓冲区作为格式化源参数,读写同一内存的顺序不确定,会导致不可预测的结果。

解决方案

方案1:使用固定大小字符数组(C风格,适合嵌入式环境)

定义一个足够大的可写缓冲区,用安全的方式拼接内容:

// 定义64字节缓冲区,足够容纳浮点数、换行符及终止符
char mstr[64] = {0}; 

// 先写入浮点数(初始缓冲区为空,不需要%s拼接)
sprintf_P(mstr, PSTR("%f"), z_values[x][y] * 1000);
// 拼接换行符,用strcat_P更高效(针对PROGMEM字符串)
strcat_P(mstr, PSTR("\n"));

// 传递给函数
RTS_SndData(mstr, AUTO_BED_LEVEL_MESH_VP);

如果要多次拼接且避免溢出,推荐用snprintf_P限制写入长度:

char mstr[64] = {0};
// 写入浮点数,确保不超过缓冲区大小
snprintf_P(mstr, sizeof(mstr), PSTR("%f"), z_values[x][y] * 1000);
// 拼接换行符,计算剩余空间
size_t current_len = strlen(mstr);
snprintf_P(mstr + current_len, sizeof(mstr) - current_len, PSTR("\n"));

方案2:使用C++ std::string(更接近PHP的字符串操作)

如果Marlin环境支持C++标准库,用std::string更安全,无需手动管理缓冲区:

#include <string> // 若未包含需添加

std::string mstr;
// 先将浮点数格式化为字符串,存入临时缓冲区
char float_buf[32];
sprintf_P(float_buf, PSTR("%f"), z_values[x][y] * 1000);
// 像PHP一样直接拼接
mstr += float_buf;
mstr += "\n";

// 转换为C风格字符串传递给函数
// 若RTS_SndData接受const char*,用mstr.c_str()
// 若必须非const char*,用&mstr[0](C++11及以后)或const_cast
RTS_SndData(const_cast<char*>(mstr.c_str()), AUTO_BED_LEVEL_MESH_VP);

关键注意事项

  • 永远不要用字符串字面量(如"")作为可写缓冲区,它们存放在只读内存区,修改会导致崩溃。
  • 避免在sprintf/sprintf_P中同时将目标缓冲区作为源参数,这属于未定义行为。
  • 嵌入式环境中优先用带长度限制的snprintf_P,防止缓冲区溢出引发硬件故障。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 16:10:33