c++ - Segfault when imbueing stringstream with custom locale -
based on answers here question of how format numbers comma, using following code:
#include <locale> #include <stringstream> namespace { class comma_numpunct : public std::numpunct<char> { protected: virtual char do_thousands_sep() const { return ','; } virtual std::string do_grouping() const { return "\03"; } }; } /* convert number string using comma thousands separator. */ string thousands(const int x) { /* custom locale ensure thousands separator comma */ comma_numpunct* comma_numpunct_ptr = new comma_numpunct(); std::locale comma_locale(std::locale(), comma_numpunct_ptr); stringstream ss; ss.imbue(comma_locale); // apply locale stringstream ss << x; /* garbage collection */ delete comma_numpunct_ptr; return ss.str(); }
gdb gives following backtrace:
program received signal sigsegv, segmentation fault. 0x0000000000000021 in ?? () (gdb) bt #0 0x0000000000000021 in ?? () #1 0x00007ffff7701535 in std::locale::_impl::~_impl() () /usr/lib/x86_64-linux-gnu/libstdc++.so.6 #2 0x00007ffff770166d in std::locale::~locale() () /usr/lib/x86_64-linux-gnu/libstdc++.so.6 #3 0x000000000044b93e in thousands (x=358799) @ ../globals_utilities.cpp:104 #4 0x000000000045650d in main (argc=1, argv=0x7fffffffdf58) @ ../main.cpp:67
so, problem (i believe) attempt @ freeing new
'd memory. don't know how work around this. (i can't use std::unique_ptr
because i'm not compiling c++11 support.)
how can fix segfault without leaking memory?
your problem locale facet (numpunct). if pass locale via constructor , references of facet 0 locale delete facet.
you might do:
comma_numpunct(size_t refs = 0) : numpunct(refs) {}
and
comma_numpunct* comma_numpunct_ptr = new comma_numpunct(1);
or better omit:
// double delete // delete comma_numpunct_ptr;
you may omit allocation of facet:
string thousands(const int x) { comma_numpunct numpunct(1); std::locale comma_locale(std::locale(), &numpunct); std::stringstream ss; ss.imbue(comma_locale); ss << x; return ss.str(); }
from 22.3.1.1.2 class locale::facet
the refs argument constructor used lifetime management.
— refs == 0, implementation performs delete static_cast(f) (where f pointer facet) when last locale object containing facet destroyed; refs == 1, implementation never destroys facet.
Comments
Post a Comment