C++ Managed and unmanaged code with std library

Answered C++ Managed and unmanaged code with std library

  • terça-feira, 31 de julho de 2012 19:54
     
     

    Hi,

    I've written a managed DLL that I'm calling from unmanaged code that is a win32 application and uses the std library.  The DLL functions correctly. I.e., the functions that the DLL performs all work correctly.  The code compiles with no warnings or errors and runs correctly.  However, when debugging, if I  use

    _CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF); and _CrtDumpMemoryLeaks(); to check for memory leaks, I always get detected memory leaks.  This only occurs when I use the std library.  I'm using <string>, <list>, <fstream>, and <iostream>.  If I remove the std library calls I get no memory leaks.

    Does anyone know if this is an issue with Visual C++ or is this my issue?  I'm running Visual Studio 2010 SP1.  Here's the VS 2010 About box information.

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

    Installed Version: Professional

    Microsoft Office Developer Tools   xxxxx-xxx-xxxxxxx-xxxxx
    Microsoft Office Developer Tools

    Microsoft Visual Basic 2010   xxxxx-xxx-xxxxxxx-xxxxx
    Microsoft Visual Basic 2010

    Microsoft Visual C# 2010   xxxxx-xxx-xxxxxxx-xxxxx
    Microsoft Visual C# 2010

    Microsoft Visual C++ 2010   xxxxx-xxx-xxxxxxx-xxxxx
    Microsoft Visual C++ 2010

    Microsoft Visual F# 2010   xxxxx-xxx-xxxxxxx-xxxxx
    Microsoft Visual F# 2010

    Microsoft Visual Studio 2010 Team Explorer   xxxxx-xxx-xxxxxxx-xxxxx
    Microsoft Visual Studio 2010 Team Explorer

    Microsoft Visual Web Developer 2010   xxxxx-xxx-xxxxxxx-xxxxx
    Microsoft Visual Web Developer 2010

    Crystal Reports Templates for Microsoft Visual Studio 2010   
    Crystal Reports Templates for Microsoft Visual Studio 2010

    Hotfix for Microsoft Visual Studio 2010 Professional - ENU (KB2522890)   KB2522890
    This hotfix is for Microsoft Visual Studio 2010 Professional - ENU.
    If you later install a more recent service pack, this hotfix will be uninstalled automatically.
    For more information, visit http://support.microsoft.com/kb/2522890.

    Hotfix for Microsoft Visual Studio 2010 Professional - ENU (KB2529927)   KB2529927
    This hotfix is for Microsoft Visual Studio 2010 Professional - ENU.
    If you later install a more recent service pack, this hotfix will be uninstalled automatically.
    For more information, visit http://support.microsoft.com/kb/2529927.

    Hotfix for Microsoft Visual Studio 2010 Professional - ENU (KB2542054)   KB2542054
    This hotfix is for Microsoft Visual Studio 2010 Professional - ENU.
    If you later install a more recent service pack, this hotfix will be uninstalled automatically.
    For more information, visit http://support.microsoft.com/kb/2542054.

    Hotfix for Microsoft Visual Studio 2010 Professional - ENU (KB2548139)   KB2548139
    This hotfix is for Microsoft Visual Studio 2010 Professional - ENU.
    If you later install a more recent service pack, this hotfix will be uninstalled automatically.
    For more information, visit http://support.microsoft.com/kb/2548139.

    Hotfix for Microsoft Visual Studio 2010 Professional - ENU (KB2549864)   KB2549864
    This hotfix is for Microsoft Visual Studio 2010 Professional - ENU.
    If you later install a more recent service pack, this hotfix will be uninstalled automatically.
    For more information, visit http://support.microsoft.com/kb/2549864.

    Hotfix for Microsoft Visual Studio 2010 Professional - ENU (KB2635973)   KB2635973
    This hotfix is for Microsoft Visual Studio 2010 Professional - ENU.
    If you later install a more recent service pack, this hotfix will be uninstalled automatically.
    For more information, visit http://support.microsoft.com/kb/2635973.

    Microsoft Visual Studio 2010 Professional - ENU Service Pack 1 (KB983509)   KB983509
    This service pack is for Microsoft Visual Studio 2010 Professional - ENU.
    If you later install a more recent service pack, this service pack will be uninstalled automatically.
    For more information, visit http://support.microsoft.com/kb/983509.

    Microsoft Visual Studio 2010 SharePoint Developer Tools   10.0.40219
    Microsoft Visual Studio 2010 SharePoint Developer Tools

    Security Update for Microsoft Visual Studio 2010 Professional - ENU (KB2645410)   KB2645410
    This security update is for Microsoft Visual Studio 2010 Professional - ENU.
    If you later install a more recent service pack, this security update will be uninstalled automatically.
    For more information, visit http://support.microsoft.com/kb/2645410.

    XtraReports package   1.0
    XtraReports package

    Thanks in advance.

    - Neil Shore

Todas as Respostas

  • terça-feira, 31 de julho de 2012 22:52
     
     Resposta Proposta

    I've written a managed DLL that I'm calling from unmanaged code that is a win32 application and uses the std library.  The DLL functions correctly. I.e., the functions that the DLL performs all work correctly.  The code compiles with no warnings or errors and runs correctly.  However, when debugging, if I  use

    _CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF); and _CrtDumpMemoryLeaks(); to check for memory leaks, I always get detected memory leaks.  This only occurs when I use the std library.  I'm using <string>, <list>, <fstream>, and <iostream>.  If I remove the std library calls I get no memory leaks.

    Can you reproduce it with a simple example that anyone could try?

    Dave

  • quarta-feira, 1 de agosto de 2012 06:00
    Moderador
     
     

    Hi,

    Maybe you can try to use some tools to find the memory leaks.
    http://social.msdn.microsoft.com/Forums/en/vcgeneral/thread/ace5d884-7f82-4177-8a18-84a4b6034aaa

    Best regards,
    Jesse


    Jesse Jiang [MSFT]
    MSDN Community Support | Feedback to us

  • quarta-feira, 1 de agosto de 2012 12:17
     
     

    Hi Jesse,

    Thanks for the reference.  I've downloaded Visual Leak tester to try it out.

    Best Regards,

    - Neil Shore

  • quarta-feira, 1 de agosto de 2012 12:25
     
     

    Hi David,

    I do have code I could send.  It is a complete VS 2012 solution containing 4 projects, the managed DLL project, a managed Console project to test the DLL, an unmanaged Console project to test the DLL and an unmanaged Win32 project to test the DLL. 

    Do you recommend that I open a support incident?

    Regards,

    - Neil Shore

  • quarta-feira, 1 de agosto de 2012 13:18
     
     

    >I do have code I could send.  It is a complete VS 2012 solution containing 4 projects, the managed DLL project, a managed Console project to test the DLL, an unmanaged Console project to test the DLL and an unmanaged Win32 project to test the DLL. 

    It'd be better if you could distill it into a single console
    application - make it as trivial as possible so that there's no
    ambiguity as to the cause of the problem.

    Dave

  • terça-feira, 14 de agosto de 2012 07:09
    Moderador
     
     

    Hi,

    Would you mind letting me know the result of the suggestions? If you need further assistance, feel free to let me know. I will be more than happy to be of assistance.

    Best regards,
    Jesse


    Jesse Jiang [MSFT]
    MSDN Community Support | Feedback to us

  • quarta-feira, 15 de agosto de 2012 12:26
     
      Contém Código

    Hi Jesse,

    I've built a test solution that uses the managed dll as a library.  The solution has a "debug" build and a "NDTConfigStandaloneTestWithSTD" build.  The only difference between the builds is the addition of some lines of code using STD library.  Both builds call

    _CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF); and

    ...

    _CrtDumpMemoryLeaks();

    Running the STD build returns memory leaks.  Running the non STD build returns no memory leaks.  Do you want me to send you the solution?  If you do, what is the best way to "package" it for this forum?  The project looks like this:

    I'm attaching to source for _tmain.  Maybe you can see something I'm missing.

    // NDTConfigStandaloneTest.cpp : Defines the entry point for the console application.
    // Copyright (c) 2012, Laser Technology, Inc.  All rights reserved
    //
    
    #include "stdafx.h"
    #include <conio.h>
    #include <direct.h>
    #include <crtdbg.h>
    
    #if defined( USE_STD )
    #include <string>
    #include <list>
    #include <fstream>
    #include <iostream>
    #endif
    
    #include "LaserNDTConfig.h"
    
    #if defined( USE_STD )
    using namespace std;
    #endif
    
    //typedef int (__cdecl *MYPROC3)(char *szFileName);
    //typedef int (__clrcall *MYPROC1)();
    //typedef int (__clrcall *MYPROC2)(char *szFileName);
    #if defined( USE_STD )
    int DumpConfigFile (char* szFile);
    #endif
    
    #if defined( USE_STD )
    list <string> g_listSt;
    #endif
    
    
    int _tmain(int argc, _TCHAR* argv[])
    {
    	int		iRet;
    	char	szFile [1024];
    	char	szManufacturer[128];
    	char	szWorkingDirectory [1024];
    
    	_CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
    
    	printf ("laserNDT Configuration Tester\n");
    	strcpy (szFile, "LaserNDTConfiguration.xml"); 
    
    	_getcwd (szWorkingDirectory, sizeof (szWorkingDirectory) - 1);
    	printf ("Working directory:  %s\n", szWorkingDirectory);
    	printf ("Loading file:  %s\n", szFile);
    
    #if defined( USE_STD )
    	iRet = DumpConfigFile (szFile);
    	if (iRet > 0) {
    		string	st1;
    		list <string>::const_iterator c1_cIter;
    		printf (">>> config file >>>\n");
    		for (c1_cIter = g_listSt.begin (); c1_cIter !=  g_listSt.end (); c1_cIter++) {
    			st1 = (string) *c1_cIter;
    			printf ("%s\n", st1.c_str());
    		}
    	}
    	printf ("<<< end config file <<<\n\n");
    #endif
    
    	iRet = LoadLaserNDTConfigurationFromXMLFile (szFile);
    	if (iRet != 0) {
    		while (_kbhit ());
    		printf ("\nError %d opeing configuration file.\nPress any key to exit\n", iRet);
    		_getch ();
    		return 1;
    	}
    
    	while (_kbhit ());
    	printf ("\nPress any key to test bool functions\n");
    	_getch ();
    
    	printf ("IsFilterControlAvailible returns %d\n", IsFilterControlAvailible ());
    	printf ("IsExcitationControlAvailible returns %d\n\n", IsExcitationControlAvailible());
    
    	printf ("IsThermalTestAvailible returns %d\n", IsThermalTestAvailible());
    	printf ("IsThermalTestHardwareAvailible returns %d\n\n", IsThermalHardwareControlEnabled());
    
    	printf ("IsVacuumTestAvailible returns %d\n", IsVacuumTestAvailible());
    	printf ("IsVacuumTestHardwareAvailible returns %d\n\n", IsVacuumHardwareControlEnabled());
    
    	printf ("IsPhaseReversalTestAvailible returns %d\n", IsPhaseReversalTestAvailible());
    	printf ("IsThereTestExternalButton returns %d\n", IsThereTestExternalButton(THERMAL));
    	printf ("IsThereTestIndicator returns %d\n", IsThereTestIndicator(THERMAL));
    	printf ("IsLTIBusBoardPresentName returns %d\n", IsLTIBusBoardPresentName ("Motor"));
    	printf ("IsLTIBusBoardPresent returns %d\n", IsLTIBusBoardPresent(LASER_MOTOR_BOARD));
    	printf ("IsAutoCalibrationAvailible returns %d\n", IsAutoCalibrationAvailible());
    	printf ("IsDualShearAvailible returns %d\n", IsDualShearAvailible());
    	printf ("IsLaserSoftwareControllAvailible returns %d\n",IsLaserSoftwareControllAvailible());
    	printf ("IsLocalProgrammedScanAvailible returns %d\n", IsLocalProgrammedScanAvailible());
    	printf ("IsPhaseDevicePiezo returns %d\n", IsPhaseDevicePiezo());
    	printf ("IsProduct5100 return %d\n", IsProduct5100 ());
    	printf ("SimulateVideo %d\n", SimulateVideo ());
    	printf ("IsLTIACADEnabled %d\n", IsLTIACADEnabled ());
    
    	while (_kbhit ());
    	printf ("\nPress any key to test string functions\n");
    	_getch ();
    	iRet = GetLaserManufacturer (szManufacturer, sizeof (szManufacturer) -1);
    	printf ("GetLaserManufacturer returned %d\n", iRet);
    	if (iRet > 0)
    		printf ("	Laser Manufacturer is: %s\n", szManufacturer);
    
    
    	while (_kbhit ());
    	printf ("Press any key to exit\n");
    	_getch ();
    
    	_CrtDumpMemoryLeaks();
    	return 0;
    }
    
    
    #if defined( USE_STD )
    
    int DumpConfigFile (char* szFile)
    {
    	int			iLines;
    	ifstream	file;
    	string		sz;
    
    	iLines = 0;
    	file.open (szFile);
    	g_listSt.clear ();
    
    	while (!file.eof()) {
    		getline (file, sz, '\n');
    		g_listSt.push_back (sz);
    		iLines++;
    	}
    	file.close ();
    
    	return iLines;
    }
    #endif
    

    Let me know what you think.

    Best Regards,

    - Neil Shore

  • quarta-feira, 15 de agosto de 2012 13:14
     
     

    >_CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF); and

    As you're using _CRTDBG_LEAK_CHECK_DF

    there's no need to call _CrtDumpMemoryLeaks();

    Try with it removed.

    Dave

  • quarta-feira, 15 de agosto de 2012 13:30
     
      Contém Código

    Hi David,

    I don't think you are correct.  The call to _CrtDumpMemoryLeaks(); is required.  If there are no leaks then nothing is output to the Debug window.  If there are leaks them a list of the leaks are printed.  I've excerpted the documentation about using _CRTDBG_LEAK_CHECK_DF below for you to check.

    ------------------------------>

    By including crtdbg.h, you map the malloc and free functions to their debug versions, _malloc_dbg and _free_dbg, which keep track of memory allocation and deallocation. This mapping occurs only in a debug build (in which _DEBUG is defined). Release builds use the ordinary malloc and free functions.

    The #define statement maps the base versions of the CRT heap functions to the corresponding debug versions. You do not absolutely need this statement, but without it, the memory leak dump will contain less useful information.

    Once you have added the previous statements, you can dump memory leak information by including the following statement in your program:

    _CrtDumpMemoryLeaks();
    

    When you run your program under the debugger, _CrtDumpMemoryLeaks displays memory leak information in the Output window. The memory leak information looks like this:

    <---------------------------

    Best Regards,

    - Neil Shore

  • quarta-feira, 15 de agosto de 2012 13:53
     
     

    >I don't think you are correct.  The call to _CrtDumpMemoryLeaks(); is required.

    Try it ;)

    #include "stdafx.h"
    #include <malloc.h>
    #include <crtdbg.h>

    int _tmain(int argc, _TCHAR* argv[])
    {
        _CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF |
    _CRTDBG_LEAK_CHECK_DF);
        void * pLeak = malloc( 100 );
        return 0;
    }

    Detected memory leaks!
    Dumping objects ->
    {100} normal block at 0x001F87D0, 100 bytes long.
     Data: <                > CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD
    CD Object dump complete.

    Dave

  • quinta-feira, 16 de agosto de 2012 12:46
     
     

    Hi David,

    I tried your sample and it worked as you said.

    I think I've figured out my issue.  I insert the _CrtDumpMemoryLeaks function as the last statement of MY code.  When using the STD library there must be some code that runs in the C++ startup module, before _tmain() is called, that is allocating memory.  The memory is deallocated after my return (the return from _tmain).  My call to _CrtDumpMemoryLeaks shows the as yet not deallocated memory for the STD library.  Of course, when not using the STD library no extra memory is allocated.

    Let me know what you think.

    - Neil

  • quinta-feira, 16 de agosto de 2012 13:02
     
     Respondido

    >I think I've figured out my issue.  I insert the _CrtDumpMemoryLeaks function as the last statement of MY code.  When using the STD library there must be some code that runs in the C++ startup module

    That's right, your collection was declared globally so its destructor
    would run after your main exited - which is why I suggested what I
    did. :)

    Dave

    • Marcado como Resposta ShoreLaserMan quinta-feira, 16 de agosto de 2012 13:57
    •