Could be a memory leak on std::locale?

Flaviu_ 1,031 Reputation points
2023-11-28T08:22:42.57+00:00

I have a code:

std::stringstream ss;

std::locale loc(ss.getloc(), new custom_numpunct());

ss.imbue(loc);

Where custom_numpunct is defined as:

class custom_numpunct : public std::numpunct<char>
{
protected:
	virtual char do_thousands_sep() const
	{
		return ',';
	}

	virtual std::string do_grouping() const
	{
		return "\3";
	}
};

My question is: the line

std::locale loc(ss.getloc(), new custom_numpunct());

could be a memory leak? Like 7th constructor from this official page: https://en.cppreference.com/w/cpp/locale/locale/locale

std::locale l4(l1, new std::codecvt_utf8<wchar_t>);
Developer technologies | C++
0 comments No comments
{count} votes

Accepted answer
  1. Viorel 122.6K Reputation points
    2023-11-28T09:22:31.6766667+00:00

    These classes are derived from the locale::facet class, which implements Reference Counting (according to documentation). Therefore, in both of your examples, the objects will be deleted.

    You can add a destructor to custom_numpunct to see that it is executed.

    (However, some adjustments are needed to allocate the custom_numpunct or codecvt_utf8 objects on the stack).


1 additional answer

Sort by: Most helpful
  1. RLWA32 49,636 Reputation points
    2023-11-28T09:12:08.3033333+00:00

    There does not appear to be a memory leak. Try this using the CRT Library debugging features -

    // LocLeak.cpp : This file contains the 'main' function. Program execution begins and ends there.
    //
    
    #ifdef _DEBUG
    #define _CRTDBG_MAP_ALLOC
    #include <stdlib.h>
    #include <crtdbg.h>
    #ifndef DBG_NEW
    #define DBG_NEW new ( _NORMAL_BLOCK , __FILE__ , __LINE__ )
    #define new DBG_NEW
    #endif
    #endif  // _DEBUG
    
    #include <iostream>
    #include <locale>
    #include <sstream>
    
    class custom_numpunct : public std::numpunct<char>
    {
    protected:
        virtual char do_thousands_sep() const
        {
            return ',';
        }
    
        virtual std::string do_grouping() const
        {
            return "\3";
        }
    };
    
    // Only dynamically allocated int is leaked
    
    int main()
    {
        _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
    
        int *pInt = ::new int;
    
        std::stringstream ss;
    
        std::locale loc(ss.getloc(), ::new custom_numpunct );
    
        ss.imbue(loc);
    
        ss << 1000000;
    
        std::cout << ss.str() << std::endl;
    
        return 0;
    }
    
    
    1 person found this answer helpful.
    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.