1

When I run the following source code, got "Segmentation fault (core dumped)" at line#3

char s[] = "helloworld";
const std::collate<char>* pc = &std::use_facet<std::collate<char> >(std::locale("en_US"));
std::string str = pc->transform(s, s + std::strlen(s));
std::cout << str.length() << "," << str << std::endl;

If I replace the line#2 with

const std::collate<char>* pc = new std::collate_byname<char>("en_US");

I can get the correct result. I think this two lines' result should be same, they all get a collate from the execution environment, so why the former got a fault? Did I do something wrong?

PS: The c++ compiler is g++ (GCC) 4.4.7 20120313 (Red Hat 4.4.7-3).

songyuanyao
  • 169,198
  • 16
  • 310
  • 405

1 Answers1

4

Reading the docs of use_facet:

The reference returned by this function is valid as long as any std::locale object exists that implements Facet.

You're creating a temporary std::locale in your code, so that temporary is destroyed at the end of the expression, and you're left with a dangling pointer. Like this, it should work:

char s[] = "helloworld";
std::locale en_US("en_US");
const std::collate<char>* pc = &std::use_facet<std::collate<char> >(en_US);
std::string str = pc->transform(s, s + std::strlen(s));
std::cout << str.length() << "," << str << std::endl;
Matthieu M.
  • 287,565
  • 48
  • 449
  • 722
Angew is no longer proud of SO
  • 167,307
  • 17
  • 350
  • 455
  • 1
    I've thought wrongly that `std::locale("en_US")` will be a global object, but only `std::locale()` and `std::locale::classic()` are global in fact. – songyuanyao Feb 17 '14 at 08:48
  • 1
    @songyuanyao To put it precisely: a `std::locale` object is just a dumb(ish) collection of pointers to facets, the facets themselves being reference-counted. `classic()` returns an actual C++ reference to the global C-locale instance, while the empty `std::locale` ctor returns a copy of the global locale (incrementing the ref-count on its facets). Constructing a different locale will give you a locale object whose facets are (potentially) only used by that object - ref. count 1. Lose that object and facets go down to 0 and are destroyed. – Angew is no longer proud of SO Feb 17 '14 at 09:17