Why does this code leak memory?

I discovered that calling typeid seem to cause memory leak but I don't know why. Here is my full source code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

template<typename T> const char* getTypeId(T &cls)
 {
	
	try {
	return typeid(T).name(); // this leaks ???
	}
	catch(...) {}
	
	return "";
}


template <class T> void checkPointer(T * ptr)
{
 std::string type = getTypeId(ptr);

 throwOnInvalidPtr(ptr,type);
}

void throwOnInvalidPtr(const void *ptr, string type)
{
 if(!logLeaks) return;

 if(!ptr)
	throw string("null pointer ") + type;
}


commenting out std::string type = getTypeId(ptr); fixes memory leak. any ideas why?

thanks
What makes you think this code has a memory leak?
If you are using Visual Studio, then it is false positive in leak detector.
Because like I said commenting the call to getTypeId out fixes memory from leaking.
I used the windows task manager to see how the memory allocation rises too fast. when commented out the memory allocation doesnt increase much.
Compiler/version?
Everything is okay for me.
Also note that type_info object created by typeid is not deleted to allow different typeid expressions to refer to the same object (caching)

how the memory allocation rises too fast
Did you consider that std::string uses dynamic memory and Windows do not reclaim freed memory instantly unless most of physical memory is allocated.
I'm using:

Microsoft Visual Studio 2010
Version 10.0.40219.1 SP1Rel
Microsoft .NET Framework
Version 4.5.50938 SP1Rel

I guess the memory leak is connected to the string more than typeid.

I tested like this:

1
2
3
4
5
6
7
template <class T> void checkPointer(T * ptr)
{
 std::string type = "test test test test test test test test test test test test test ";//getTypeId(ptr);

 throwOnInvalidPtr(ptr,type);
}


and that causes big memory allocation. (memory allocation rises to hundreds of mb in seconds)

Now I don't understand why is string not freed?
Last edited on
I remember something about bug in standard library implementation in VS 2010.
Fixed in VS2011

Get something modern, like 2015 Community edition.

EDIT: Here is bug report https://connect.microsoft.com/VisualStudio/feedback/details/596565/memory-leak-with-std-vector-std-string-insert-using-const-std-string#details
Last edited on
std::typeinfo::name() returns an implementation-defined NTBS.

The standard does not specify what the storage duration (life-time) of this NTBS ought to be. Since programmers may store the value of the returned pointer, and then try to access the NTBS later, every implementation plays safe by never releasing the memory for the NTBS. Current implementations return the same pointer for multiple calls to std::typeinfo::name() for the same type. So, if your program calls template<typename T> const char* getTypeId(T &cls) for a very large number of different types, the memory required for the MTBS may be high.

Old Microsoft implementations - VS 2010 or earlier - were notorious for creating a new NTBS, each time std::typeinfo::name() was called for the same type. In this case, you should update to a more current version.

We can check it out by writing a small program:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include <iostream>
#include <cstring>
#include <typeinfo>
#include <set>

static std::set< const void* > ntbs_locations ;

void dump( const std::type_info& ti )
{
    const auto ptr = ti.name() ;
    const void* pv = ptr ;
    if( ntbs_locations.insert(pv).second )
    {
        static int cnt = 0 ;
        std::cout << ++cnt << ". " << ptr << " (NTBS at: " << pv << ")\n" ;
    }
}

int main()
{
    for( int i = 0 ; i < 100 ; ++i )
    {
        dump( typeid( std::strtol ) ) ;
        dump( typeid( std::cin.getloc() ) ) ;
        dump( typeid( std::strncmp ) ) ;
        dump( typeid( std::cout.rdbuf() ) ) ;
        dump( typeid( typeid(int) ) ) ;
    }

    std::cout << "\n#ntbs: " << ntbs_locations.size() << '\n' ;
}

With a reasonable implementation, #ntbs would be 5, not 500.
http://coliru.stacked-crooked.com/a/89eee8b6d4a74c4e
I upgraded visual studio 10 to newest service pack but the problem remains. I really think its the string eating up the memory, somehow
Last edited on
Update VS itself. Service pack does not fix problem for some people:
It turned out that this bug was fixed in VS2010SP1. Though on my machine I had the old version of files -- despite the SP being installed, and even using 'reapply' did not cure the situation. It got fixed after I asked to remove the SP1 entirely, then applied it again from scratch.
http://stackoverflow.com/a/16759102

There is no reason to use VS2010. Use 2015 Community edition, which is free and has almost complete C++11 and C++14 support
@JLBorges I ran your code in vs10 and the result was 5.

downloading vs15 now.
Well I'm on VS2015 now only to say my program leaks more memory than before.
The memory taken rises around 10k per second.
Last edited on
Are you sure that it is a leak and not "memory pages which system just does not want to reclaim now because there is no need to do so?" or memory fragmentation issue. What happens if you leave program for several hours? Does it stabilizes or eats all memory and starts swapping?

Edit: try to use Memory debugging tools in VS http://blogs.msdn.com/b/visualstudioalm/archive/2014/11/13/memory-usage-tool-while-debugging-in-visual-studio-2015.aspx
(Actually when I though, increased memory consumption might be a case of debug build saving logs or something)
Last edited on
I dont know but I noticed release build memory allocation stays still at 50K. I think the problem is somehow connected to debugging. when debugging the app the memory allocation goes to 2GB in minute and app crashes. release seems stable.
Topic archived. No new replies allowed.