More on the socket server VS2005 'leaks'

A while ago I reported that I’d been seeing very strange memory usage patterns in the debug build of the simple echo server when built with Visual Studio 2005 using the standard version of STL that ships with it. The thing that interests me most about this leak is that it seems to be more of a ‘strange allocation strategy’ rather than a leak as I was previously able to get the memory usage to grow to a large amount and then suddenly it dropped back to something reasonable and then started to grow again. The other interesting thing is that it doesn’t exist if I build with STLPort.

Today I’ve finally had some time to build and test the server properly and I’m pretty sure that I’ve found the location of the leak. In the next few days I hope to release a new build of the servers (using the existing freely available codebase) but including the couple of changes required to get the code to build with VS2005 and the bug fixes that I’ve mentioned in the comments to the original postings. This will be the final (I hope) release of this code.

The leak occurs in this code:

template <class T>
_tstring ToString(T num)
{
   _tstring strNum = _T("");
   
   {
      std::strstream buf;

      buf << num << std::ends;
   
#ifdef _UNICODE
      std::string temp = buf.str();
   
      USES_CONVERSION;
   
      strNum = A2W(temp.c_str());
#else 
      strNum = buf.str();
#endif
      buf.freeze(false);
   }
   
   return strNum;
}

If I comment out the body of the method and just return an empty string then the leak vanishes. The location of the leak explains why the debug build leaks so much more than the release build; the debug build calls this function to convert the current thread id to a string every time it outputs a debug log line, and in the release build the debug log code doesn’t exist.

The fact that the leak occurs in all builds, unicode and non-unicode means we can discard any thoughts of the narrow to wide string conversion code being at fault. Having traced through the code it looks like I’m not abusing the STL; I’ve yet to check my references but calling str() on a strstream gives the caller ownership of the buffer within the strstream and calling freeze(false) gives it back to the strstream. Tracing through a single call shows that the buffer is correctly destroyed when the strstream goes out of scope.

More investigation is needed but I’m quite pleased to have located the leak…