I have a function that uses the Boost.DateTime library for generating the current GMT/UTC date and time string (live example).
std::string get_curr_date() { auto date = boost::date_time::second_clock<boost::posix_time::ptime>::universal_time(); boost::posix_time::time_facet* facet = new boost::posix_time::time_facet("%a, %d %b %Y %H:%M:%S GMT"); std::ostringstream os; os.imbue(std::locale(os.getloc(), facet)); os << date; return os.str(); }
This is mostly based on Boost.DateTime's example:
//example to customize output to be "LongWeekday LongMonthname day, year" // "%A %b %d, %Y" date d(2005,Jun,25); date_facet* facet(new date_facet("%A %B %d, %Y")); std::cout.imbue(std::locale(std::cout.getloc(), facet)); std::cout << d << std::endl; // "Saturday June 25, 2005"
My code worked nicely, but now I'm feeling uneasy because of these particular lines containing new
:
boost::posix_time::time_facet* facet = new boost::posix_time::time_facet("%a, %d %b %Y %H:%M:%S GMT");
date_facet* facet(new date_facet("%A %B %d, %Y"));
As you can see, there is no delete
in Boost.DateTime's so I somehow presumed that it is imperative for me to delete
the date_facet
. I used std::unique_ptr
to wrap the new
ed time_facet
object.
std::unique_ptr<boost::posix_time::time_facet> facet(new boost::posix_time::time_facet("%a, %d %b %Y %H:%M:%S GMT"));
However, I am getting segfault errors, as you can see in here. I have also tried manually delete
ing the new
ed pointer, and am still getting the same errors (sorry, can't reproduce error in Coliru).
The time_facet
pointer is passed as an argument when constructing an std::locale
object, so I'm confused who's the one responsible for delete
ing the facet.
So here is the core of my question:
delete
the time_facet
or is the std::locale
object responsible for delete
ing it?Please note that boost::posix_time::time_facet
is derived from boost::date_time::date_facet
which is, in turn, derived from std::locale::facet
. This question might generalized to std::locale::facet
, though my problem is specific to time_facet
.
Here are some docs on std::locale
's constructors:
Am I required to delete the time_facet or is the std::locale object responsible for deleteing the it?
You're not required to delete the time_facet
so long as time_facet
derives from std::locale::facet
, which it should. The std::locale::facet
is a base class that all facets should derive from that implement a form of reference counting. The standard says this:
§ 22.3.1.6
Once a facet reference is obtained from a locale object by calling
use_facet<>
, that reference remains usable, and the results from member functions of it may be cached and re-used, as long as some locale object refers to that facet.
Once all references of the facet are not being used, the destructor of std::locale
will manage and delete references to the facet if its ref count is 0.
This is all specified in §22.3.1.1.2 in the C++11 standard. Where it states:
The refs argument to the constructor is used for lifetime management.
— For
refs == 0
, the implementation performsdelete static_cast<locale::facet*>(f)
(where f is a pointer to the facet) when the last locale object containing the facet is destroyed; forrefs == 1
, the implementation never destroys the facet.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With