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

在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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 12:46:05