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

如何避免C++中unique_ptr内存重叠?定时器开发问题排查

问题根源与解决方案

你的问题出在对localtime函数的返回值理解错误,以及错误地用std::unique_ptr接管了不属于动态分配的内存:

核心错误点

  • localtime函数返回的指针指向全局静态分配的缓冲区,每次调用localtime都会将结果覆盖写入这块内存,也就是说两次调用返回的指针本质上指向同一块地址。
  • 你用std::unique_ptr接管这个指针是错误的:unique_ptr默认的删除器是delete,但这块静态内存根本不是通过new分配的,后续智能指针尝试释放它会触发未定义行为;同时两个unique_ptr指向同一块静态内存,自然会导致两个Date对象的时间完全相同。

修正方案

你需要自己动态分配struct tm的内存,并将localtime的结果拷贝进去,或者使用线程安全的时区转换函数来避免静态缓冲区的问题。

方案1:拷贝静态缓冲区内容到动态内存

using namespace std;
time_t localTime = time(nullptr);
// 先获取静态缓冲区的时间结构,再拷贝到动态分配的tm中
struct tm* tempTm = localtime(&localTime);
unique_ptr<struct tm> currentTime(new struct tm(*tempTm));
startDate = Date(std::move(currentTime));

time_t endTime = time(nullptr) + duration;
tempTm = localtime(&endTime);
unique_ptr<struct tm> timerEndTime(new struct tm(*tempTm));
endDate = Date(std::move(timerEndTime));

方案2:使用线程安全的时区转换函数

如果是POSIX系统(Linux、macOS等),可以用localtime_r;如果是Windows系统,用localtime_s,这类函数会将结果写入你提供的缓冲区,避免依赖静态全局内存:

POSIX系统示例

using namespace std;
time_t localTime = time(nullptr);
unique_ptr<struct tm> currentTime(new struct tm);
// 将结果写入自己分配的tm缓冲区
localtime_r(&localTime, currentTime.get());
startDate = Date(std::move(currentTime));

time_t endTime = time(nullptr) + duration;
unique_ptr<struct tm> timerEndTime(new struct tm);
localtime_r(&endTime, timerEndTime.get());
endDate = Date(std::move(timerEndTime));

Windows系统示例

using namespace std;
time_t localTime = time(nullptr);
unique_ptr<struct tm> currentTime(new struct tm);
// localtime_s需要返回码检查,这里简化示例
localtime_s(currentTime.get(), &localTime);
startDate = Date(std::move(currentTime));

time_t endTime = time(nullptr) + duration;
unique_ptr<struct tm> timerEndTime(new struct tm);
localtime_s(timerEndTime.get(), &endTime);
endDate = Date(std::move(timerEndTime));

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 02:05:12