You need to enable JavaScript to run this app. C++11保存程序运行起止时间戳时两值完全一致的问题解决
优惠活动
大模型
产品
解决方案
定价
更多

C++11保存程序运行起止时间戳时两值完全一致的问题解决

问题根因

你的判断完全正确:问题确实出在共享缓存覆盖上。
std::localtime()、std::asctime() 都是C标准库提供的老旧接口,均不具备重入安全性:两个函数内部都使用进程内的全局静态内存块存储计算、格式化结果,每次调用都会直接写入、覆盖这块共享内存的内容。
对应到你的代码执行流程:

  1. 启动时刻第一次调用接口时,格式化好的启动时间字符串被写入全局共享缓存,你把这个缓存的地址赋值给了 t_start 指针——此时 t_start 没有持有独立的字符串内存,只是指向了这块会被反复覆盖的公共区域。
  2. 5秒休眠结束后,第二次调用 std::localtime() 和 std::asctime() 时,结束时刻的时间字符串被直接写进了同一块全局共享缓存,把原来存的启动时间内容完全覆盖了。此时 t_start 和 t_end 指向的是同一块内存里的同一个结束时间字符串,自然打印结果完全一致。
    你之前测试“刚启动时打印t_start能拿到正确值”,本质上是因为第一次调用完之后还没做第二次覆盖,缓存里还存着启动时间的内容;等到要在最后统一打印时,缓存早就被第二次的结果覆盖了。
修复方案

根据不同的使用场景,可以选择这几种零风险的实现方式:

  • 最直接的适配修改:拿到共享缓存里的字符串后,立刻把内容拷贝到自己管理的独立内存中,从根源上避免被后续调用覆盖。比如把原来的字符指针替换成固定大小的字符数组(asctime 格式化后的字符串固定最长26字符,包含末尾结束符,开27字节的数组足够存储),拷贝完成后后续的接口调用就不会影响已经存到自有数组里的内容。修改后的核心代码片段:
    std::time_t now = std::time(nullptr);
    char t_start[27], t_end[27];
    // 拿到共享缓存内容后立刻拷贝到自有数组
    std::strcpy(t_start, std::asctime(std::localtime(&now)));
    
    std::this_thread::sleep_for(std::chrono::nanoseconds(5000000000));
    
    now = std::time(nullptr);
    std::strcpy(t_end, std::asctime(std::localtime(&now)));
    
  • 更安全的现代接口替代:不要依赖返回全局指针的老旧接口,换成带重入保障的版本:POSIX 系统可以用 localtime_r、Windows 系统可以用 localtime_s,这类接口要求调用者传入自己申请的内存块,函数会把结果写入用户提供的内存里,完全不碰全局共享缓存,从机制上杜绝覆盖问题。
  • 更省内存的实现思路:根本不需要提前存格式化好的字符串,只需要把两次获取到的原始 std::time_t 时间值单独存下来,等到程序最后需要打印的时候,再临时对两个原始时间值做连续格式化、打印即可。这种方式不需要额外拷贝长字符串,也不会出现缓存覆盖的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.11.08 13:45:07