在asprintf参数中调用返回String的函数出现乱码,求排查
问题:asprintf调用含函数的格式化字符串出现乱码
问题描述
在asprintf的格式化参数中调用函数输出时出现乱码,相关代码及输出如下:
调用代码:
char *buf; asprintf(&buf, "%lu\t%s\n", now(), dateTimeMilDS3231());
输出结果:
1738771235 tx�?
函数dateTimeMilDS3231定义:
String dateTimeMilDS3231(uint32_t epoch = 0); ....SKIP LINES.... String dateTimeMilDS3231(uint32_t epoch) { char buf[32]; DateTime dt0(epoch); snprintf(buf, sizeof(buf), "%d-%02d-%02d %02d:%02d:%02d", dt0.year(), dt0.month(), dt0.day(), dt0.hour(), dt0.minute(), dt0.second()); return String(buf); }
问题原因
dateTimeMilDS3231返回的是Arduino的String对象,而asprintf的%s格式符需要的是有效的const char*指针。
核心问题是临时对象生命周期:直接将dateTimeMilDS3231()的返回值传入asprintf时,这个返回的String是临时对象,在asprintf开始解析可变参数后,临时对象就会被销毁。此时%s访问的是已被释放的内存区域,从而导致乱码。
解决方法
方法1:用临时变量保存String对象
先将函数返回的String存入局部变量,确保其生命周期覆盖asprintf调用过程,再通过c_str()获取有效指针:
String dtString = dateTimeMilDS3231(); asprintf(&buf, "%lu\t%s\n", now(), dtString.c_str());
方法2:让函数直接返回const char*
修改函数返回静态缓冲区的指针(注意:静态缓冲区在多线程/中断环境下可能存在竞态问题,单线程场景适用):
const char* dateTimeMilDS3231(uint32_t epoch = 0) { static char buf[32]; // 静态缓冲区生命周期贯穿程序运行 DateTime dt0(epoch); snprintf(buf, sizeof(buf), "%d-%02d-%02d %02d:%02d:%02d", dt0.year(), dt0.month(), dt0.day(), dt0.hour(), dt0.minute(), dt0.second()); return buf; }
修改后可直接调用函数传入asprintf:
asprintf(&buf, "%lu\t%s\n", now(), dateTimeMilDS3231());
内容的提问来源于stack exchange,提问作者g1ra
相关产品推荐
相关产品推荐

