Who is responsible for deleting the facet?
c++, c++11, locale
Solution
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 performs `delete static_cast<locale::facet*>(f)` (where f is a pointer to the facet) when the last locale object containing the facet is destroyed; for `refs == 1`, the implementation never destroys the facet.
Problem
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: - Am I required to `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: - MSDN - cppreference.com