为什么不同的time_t值调用ctime函数返回的字符串完全相同?
问题原因分析
该问题的核心是ctime函数的内置静态缓冲区复用机制导致的:gcc使用的glibc库中ctime的实现遵循POSIX标准规范,内部使用了全局静态缓冲区存储转换后的时间字符串,每次调用ctime都会覆盖该缓冲区的内容,且所有调用返回的指针都指向这同一个缓冲区地址。
你的代码中存在两个典型误用:
- 指针比较逻辑错误:
if (ctime(&m_start_time) == ctime(&m_end_time))比较的是两个指针的内存地址,而非字符串内容。由于两次ctime调用返回的是同一个静态缓冲区的地址,该判断永远为真,所以会固定输出check1。如果你需要比较两个时间字符串是否相等,应该使用strcmp函数,或者先把字符串拷贝到独立的存储区域后再比较。 - 输出内容重复:C++标准没有指定
<<链式调用中各个子表达式的求值顺序,你的编译器在处理cout << ... << ctime(&m_start_time) << " " << ctime(&m_end_time) << ...语句时,会先执行完两次ctime调用再执行输出操作:后一次调用ctime得到的字符串会覆盖前一次的结果,最终两个指针指向的缓冲区内容都是最后一次ctime调用的转换结果,所以输出的两个时间字符串完全一致。
修复方案
方案1:提前拷贝时间字符串到独立存储
每次调用ctime后立刻把结果拷贝到独立的std::string中,避免被后续调用覆盖:
void Logger::describe() { cout << m_start_time << " " << m_end_time << "\n"; // 提前拷贝时间字符串到独立存储 std::string start_time_str(ctime(&m_start_time)); std::string end_time_str(ctime(&m_end_time)); if (start_time_str == end_time_str) { cout << "check1\n"; } cout << m_vehicle->getPlate() << " " << start_time_str << " " << end_time_str << "\n"; }
方案2:使用线程安全的ctime_r
多线程场景下推荐使用ctime_r函数,自行提供缓冲区避免全局资源竞争:
void Logger::describe() { cout << m_start_time << " " << m_end_time << "\n"; char start_buf[32], end_buf[32]; ctime_r(&m_start_time, start_buf); ctime_r(&m_end_time, end_buf); if (strcmp(start_buf, end_buf) == 0) { cout << "check1\n"; } cout << m_vehicle->getPlate() << " " << start_buf << " " << end_buf << "\n"; }
内容的提问来源于stack exchange,提问作者Devesh Lohumi
相关产品推荐
相关产品推荐

