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 newed 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 deleteing the newed 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 deleteing the facet.
So here is the core of my question:
delete the time_facet or is the std::locale object responsible for deleteing 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