locale::_Locimp::_Locimp_dtor(_Locimp* _This) (line 169 of %Visual Studio Installation directory%\VC\crt\src\locale0.cpp) deletes all facets using DELETE_CRT macro. This macro calls the function _DebugHeapDelete which, in turn, calls the function free on the facet pointer. The function free (_free_dbg_nolock) checks whether a pointer is in the range of the crt heap and asserts if not. If a facet has been allocated by a custom allocator not on a crt heap, the assert will be triggered.
This crash is reproducible in the debug mode using tbb::scalable_malloc from the open source Thread Building blocks library. For example, overload operator new using tbb::scalable_malloc, create a facet object using the new operator and add it to the global locale - see "Steps to reproduce"
The implemenation of std::locale is now making an implicit assumption that a facet is always allocated on crt heap. This assumption is wrong. At least facets added yb the user should be destroyed by the delete operator.