I'm trying to build a timer in C++.
In my Timer class there are two Date objects that hold a std::unique_ptr<struct tm> pointer.
After I std::move the second unique_ptr in the second Date object in the following piece of code, it points to the same memory address of the first one, effectively making the two objects represent the same time, even though they should be different because of the duration offset.
using namespace std;
time_t localTime = time(nullptr);
unique_ptr<struct tm> currentTime = static_cast<unique_ptr<struct tm>>(localtime(&localTime));
startDate = Date(std::move(currentTime));
time_t endTime = time(nullptr) + duration;
unique_ptr<struct tm> timerEndTime = static_cast<unique_ptr<struct tm>>(localtime(&endTime));
endDate = Date(std::move(timerEndTime));
The Date constructor being called is this:
Date::Date(std::unique_ptr<struct tm> time) : date(std::move(time)) {}
What am I doing wrong?
It is unsurprising that the two objects overlap, because that is how
std::localtimeis supposed to work:- See
std::localtimeon cppreferenceIf you create a
std::unique_ptrthat wraps the results ofstd::localtime, you will attempt to free an object withdeletewhich was never allocated withnew, and that is undefined behavior. Write:Your
Dateconstructor should be receiving astd::tmorstd::tm const&and store it by value. If you stored a pointer, then allDates would contain the same pointer to a static internal object.How do I prevent unique pointers from overlapping in general?
This is easy to do, because
std::unique_ptris more or less fool-proof. As long as you:newmemory, orstd::make_unique, andstd::unique_ptr::release()... you won't be able to accidentally make two smart pointers overlap.