如何避免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
相关产品推荐
相关产品推荐

