1

Pls pardon me, I'm a Chinese with very poor English skill. I hope I am expressing the things correctly.

I don't think that there is a necessary to free a obj by checking some type of reference count in the world of C++. I believe that most c++ programmers would think RAII is a better method. So, why the std::facet was implemented by STL like those? For historical reason(before the C++11)?

As we known, the constructor of std::numpunct receives a parameter(size_t ref) that controls the destruction of itself. If "ref" is 0, this obj of std::numpunct would be released automatically. I have learnt how to code correctly with it and implemented a Formater as following.

struct GrouingDigits_T : std::numpunct<char> {
    GrouingDigits_T( char p_cDigits, size_t p_uiRef = 1 ) :
        std::numpunct<char>( p_uiRef ),
        m_iDigits( p_cDigits ) {};

    string do_grouping() const override {
        return string( 1, m_iDigits );
    };

    char m_iDigits = 4;
    /* yes, We Chinese people are prefer to read numbers grouped into
    4 digits. Sorry for my ugly English.*/
};

template<typename T>
inline std::string formatNumber( const T & p_Value,
                                 size_t   p_uiWidth = 0,
                                 size_t   p_uiPrec = 2,
                                 size_t   p_uiGroup = 4,
                                 char     p_cFill = ' ' ) {
    ostringstream oss;

    // solution1 likes the sample in cppreference:
    locale locGrpDigits(
        oss.getloc(),
        new GrouingDigits_T( static_cast<char>( p_uiGroup ), 0 ) );

    // solution2:
    GrouingDigits_T gd( static_cast<char>( p_uiGroup ), 1 );
    locale locGrpDigits( oss.getloc(), &gd );

    oss.imbue( locGrpDigits );

    oss << std::fixed
        << std::setw( p_uiWidth )
        << std::setprecision( p_uiPrec )
        << std::setfill( p_cFill )
        << p_Value;
    std::string strResult( oss.str() );

    if ( p_uiWidth > 0 && strResult.length() > p_uiWidth )
        return std::string( p_uiWidth, '*' );//too wide
    else
        return strResult;
};

The solution1 is more likely lead to memory leak or double-free, while the solution2 is more safe, aren't they?

Leon
  • 1,489
  • 1
  • 12
  • 31
  • I do not see why solution 1 might leak. `locGrpDigits`'s constructor increments the reference count; and when it goes out of scope when the function returns, it gets destroyed, and, presumably, its destructor decrements the reference count, sees that it's now 0, and then destroys the `std::numpunct` object. A static memory analysis tool, like `valgrind`, should be able to report any leaks. – Sam Varshavchik May 15 '19 at 05:46
  • Std::facet? I don't see you using it – JVApen May 15 '19 at 06:53
  • 1
    @JVApen: `std::numpunct` is a facet. It is derived from `locale::facet` – P.W May 15 '19 at 07:22

0 Answers0