Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. CTypedPtrArray & CStringArray

CTypedPtrArray & CStringArray

Scheduled Pinned Locked Moved C / C++ / MFC
debuggingperformancehelpquestion
9 Posts 3 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • M Offline
    M Offline
    mesajflaviu
    wrote on last edited by
    #1

    Can you tell me if I use in corect way these classes , CTypedPtrArray & CStringArray ? These are member variable to CMyDoc class :

    typedef CTypedPtrArray<CObArray,CStringArray*> CTableArray;

    class CMyDoc : public CDocument
    {
    // Attributes
    public:
    CStringArray m_saTable;
    CTableArray m_saTables;
    ...
    }

    and here is code snipped for use of them :

    m\_saTable.Add("String Test");
    m\_saTables.Add(&m\_saTable);
    CStringArray\* saTest = m\_saTables.GetAt(0);
    CString sTest = saTest->GetAt(0);
    TRACE("\\n %s \\n",sTest);
    

    but , where I need to delete elements ? I try to delete items in OnCloseDocument(...)

    void CMyDoc::OnCloseDocument()
    {
    // TODO: Add your specialized code here and/or call the base class

    m\_saTable.RemoveAll();
    m\_saTables.RemoveAll();
    TRACE("\\n %d - %d \\n",m\_saTable.GetSize(),m\_saTables.GetSize());
    
    CDocument::OnCloseDocument();
    

    }

    But with or without remove code , I didn't have memory leaks in debug window ... is really necesary to delete the items ? Any help , I will appreciated ! Thanks !

    C A M 3 Replies Last reply
    0
    • M mesajflaviu

      Can you tell me if I use in corect way these classes , CTypedPtrArray & CStringArray ? These are member variable to CMyDoc class :

      typedef CTypedPtrArray<CObArray,CStringArray*> CTableArray;

      class CMyDoc : public CDocument
      {
      // Attributes
      public:
      CStringArray m_saTable;
      CTableArray m_saTables;
      ...
      }

      and here is code snipped for use of them :

      m\_saTable.Add("String Test");
      m\_saTables.Add(&m\_saTable);
      CStringArray\* saTest = m\_saTables.GetAt(0);
      CString sTest = saTest->GetAt(0);
      TRACE("\\n %s \\n",sTest);
      

      but , where I need to delete elements ? I try to delete items in OnCloseDocument(...)

      void CMyDoc::OnCloseDocument()
      {
      // TODO: Add your specialized code here and/or call the base class

      m\_saTable.RemoveAll();
      m\_saTables.RemoveAll();
      TRACE("\\n %d - %d \\n",m\_saTable.GetSize(),m\_saTables.GetSize());
      
      CDocument::OnCloseDocument();
      

      }

      But with or without remove code , I didn't have memory leaks in debug window ... is really necesary to delete the items ? Any help , I will appreciated ! Thanks !

      C Offline
      C Offline
      Chris Meech
      wrote on last edited by
      #2

      Just one point to offer. Having two member variables named so similarly is likely going to lead to confusion at some later point. Try to come up with names that are more meaningful to the actual use of the data. For example if the strings in the string array class are all people names, cities of the world or street names, try to use that instead of m_saTable. Similarly with the member m_saTables. Just a suggestion. :)

      Chris Meech I am Canadian. [heard in a local bar] In theory there is no difference between theory and practice. In practice there is. [Yogi Berra] posting about Crystal Reports here is like discussing gay marriage on a catholic church’s website.[Nishant Sivakumar]

      M 1 Reply Last reply
      0
      • M mesajflaviu

        Can you tell me if I use in corect way these classes , CTypedPtrArray & CStringArray ? These are member variable to CMyDoc class :

        typedef CTypedPtrArray<CObArray,CStringArray*> CTableArray;

        class CMyDoc : public CDocument
        {
        // Attributes
        public:
        CStringArray m_saTable;
        CTableArray m_saTables;
        ...
        }

        and here is code snipped for use of them :

        m\_saTable.Add("String Test");
        m\_saTables.Add(&m\_saTable);
        CStringArray\* saTest = m\_saTables.GetAt(0);
        CString sTest = saTest->GetAt(0);
        TRACE("\\n %s \\n",sTest);
        

        but , where I need to delete elements ? I try to delete items in OnCloseDocument(...)

        void CMyDoc::OnCloseDocument()
        {
        // TODO: Add your specialized code here and/or call the base class

        m\_saTable.RemoveAll();
        m\_saTables.RemoveAll();
        TRACE("\\n %d - %d \\n",m\_saTable.GetSize(),m\_saTables.GetSize());
        
        CDocument::OnCloseDocument();
        

        }

        But with or without remove code , I didn't have memory leaks in debug window ... is really necesary to delete the items ? Any help , I will appreciated ! Thanks !

        A Offline
        A Offline
        Andrew Brock
        wrote on last edited by
        #3

        Firstly, make sure you are dumping the memory leaks correctly. There are a number of ways to do this, but the best is by adding

        #if defined(DEBUG) || defined(_DEBUG)
        _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
        #endif

        as early in your code as possible, in your case it will be the constructor of your App object BOOL CxxxApp::CxxxApp() This is the only way will dump the memory leaks after all static objects have been destroyed. All other ways that I know of will give misleading results if you have static objects If no destructor is provided for your class 1 is generated which calls the destructors of all member classes, otherwise the destructors of all member classes is called after your destructor code. In destructors you only need to delete memory allocated by new, malloc or the likes. Either way, your code is calling the destructors to m_saTable and m_saTables and these destructors will free any memory associated with it. Having said that, your CTableArray is storing pointers, which means that the destructor for the table will only free the pointers, and not the actual data. You will need to enumerate each item and free its memory manually. CMyDoc::OnCloseDocument() would be a good place to do this.

        INT_PTR nElements = m_saTables.GetCount();
        for (int nIndex = 0; nIndex < nElements; ++nIndex) {
        delete m_saTables.GetAt(nIndex); //assuming the elements inserted were created with "new CStringArray"
        }

        M 1 Reply Last reply
        0
        • C Chris Meech

          Just one point to offer. Having two member variables named so similarly is likely going to lead to confusion at some later point. Try to come up with names that are more meaningful to the actual use of the data. For example if the strings in the string array class are all people names, cities of the world or street names, try to use that instead of m_saTable. Similarly with the member m_saTables. Just a suggestion. :)

          Chris Meech I am Canadian. [heard in a local bar] In theory there is no difference between theory and practice. In practice there is. [Yogi Berra] posting about Crystal Reports here is like discussing gay marriage on a catholic church’s website.[Nishant Sivakumar]

          M Offline
          M Offline
          mesajflaviu
          wrote on last edited by
          #4

          Thanks for the suggestion , I will fix that .

          1 Reply Last reply
          0
          • A Andrew Brock

            Firstly, make sure you are dumping the memory leaks correctly. There are a number of ways to do this, but the best is by adding

            #if defined(DEBUG) || defined(_DEBUG)
            _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
            #endif

            as early in your code as possible, in your case it will be the constructor of your App object BOOL CxxxApp::CxxxApp() This is the only way will dump the memory leaks after all static objects have been destroyed. All other ways that I know of will give misleading results if you have static objects If no destructor is provided for your class 1 is generated which calls the destructors of all member classes, otherwise the destructors of all member classes is called after your destructor code. In destructors you only need to delete memory allocated by new, malloc or the likes. Either way, your code is calling the destructors to m_saTable and m_saTables and these destructors will free any memory associated with it. Having said that, your CTableArray is storing pointers, which means that the destructor for the table will only free the pointers, and not the actual data. You will need to enumerate each item and free its memory manually. CMyDoc::OnCloseDocument() would be a good place to do this.

            INT_PTR nElements = m_saTables.GetCount();
            for (int nIndex = 0; nIndex < nElements; ++nIndex) {
            delete m_saTables.GetAt(nIndex); //assuming the elements inserted were created with "new CStringArray"
            }

            M Offline
            M Offline
            mesajflaviu
            wrote on last edited by
            #5

            At this code :

            #if defined(DEBUG) || defined(_DEBUG)
            _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
            #endif

            give me the follow error :

            error C2501: '_CrtSetDbgFlag' : missing storage-class or type specifiers

            Because I use VC6 ?

            A 1 Reply Last reply
            0
            • M mesajflaviu

              At this code :

              #if defined(DEBUG) || defined(_DEBUG)
              _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
              #endif

              give me the follow error :

              error C2501: '_CrtSetDbgFlag' : missing storage-class or type specifiers

              Because I use VC6 ?

              A Offline
              A Offline
              Andrew Brock
              wrote on last edited by
              #6

              Possibly. Try #include <crtdbg.h> and see if that fixes the problem, otherwise try _CrtDumpMemoryLeaks(); as the last statement in the App destructor CxxxApp::~CxxxApp() I havn't used VC 6 in a many years, and it may not have these debugging functions. MSDN only has version 7.1 (2003) onwards. If I might make a suggestion, it might be an idea to upgrade. VC++ 7.1 (2003) is the latest version to support Windows 95, VC++ 8.0 (2005) is the latest version to support Windows 98/ME, VC++ 9.0 (2008) and 10.0 (2010) support Windows 2000 onwards. Unless you are wanting to support these older platforms I would suggest upgrading to at least VS 2008 Express. It is a free download from the Microsoft website with a Windows Live ID.

              1 Reply Last reply
              0
              • M mesajflaviu

                Can you tell me if I use in corect way these classes , CTypedPtrArray & CStringArray ? These are member variable to CMyDoc class :

                typedef CTypedPtrArray<CObArray,CStringArray*> CTableArray;

                class CMyDoc : public CDocument
                {
                // Attributes
                public:
                CStringArray m_saTable;
                CTableArray m_saTables;
                ...
                }

                and here is code snipped for use of them :

                m\_saTable.Add("String Test");
                m\_saTables.Add(&m\_saTable);
                CStringArray\* saTest = m\_saTables.GetAt(0);
                CString sTest = saTest->GetAt(0);
                TRACE("\\n %s \\n",sTest);
                

                but , where I need to delete elements ? I try to delete items in OnCloseDocument(...)

                void CMyDoc::OnCloseDocument()
                {
                // TODO: Add your specialized code here and/or call the base class

                m\_saTable.RemoveAll();
                m\_saTables.RemoveAll();
                TRACE("\\n %d - %d \\n",m\_saTable.GetSize(),m\_saTables.GetSize());
                
                CDocument::OnCloseDocument();
                

                }

                But with or without remove code , I didn't have memory leaks in debug window ... is really necesary to delete the items ? Any help , I will appreciated ! Thanks !

                M Offline
                M Offline
                mesajflaviu
                wrote on last edited by
                #7

                I don't know if is corect , but I think that I solve it :

                // CMyDoc.h
                typedef CTypedPtrArray CDumpArray;
                class CMyDoc : public CDocument
                {
                protected: // create from serialization only
                CMyDoc();
                DECLARE_DYNCREATE(CMyDoc)

                // Attributes
                public:
                CDumpArray m_arrDump;
                ...
                };

                // CMyDoc.cpp
                CString sText = "one";
                CStringArray* pTable = NULL;
                pTable = new CStringArray();
                pTable->Add(sText);
                sText = "two";
                pTable->Add(sText);

                m\_arrDump.Add(pTable);
                
                pTable = new CStringArray();
                sText = "three";
                pTable->Add(sText);
                sText = "four";
                pTable->Add(sText);
                
                m\_arrDump.Add(pTable);
                

                void CMyDoc::OnCloseDocument()
                {
                // TODO: Add your specialized code here and/or call the base class

                TRACE("\\n m\_arrDump %d \\n",m\_arrDump.GetSize());
                
                CString sTemp;
                for(int n = 0;n < m\_arrDump.GetSize();++n)
                {
                	TRACE("\\n StringArray no %d \\n",n);
                	CStringArray\* pTable = m\_arrDump.GetAt(n);
                	for(int t = 0;t < pTable->GetSize();++t)
                	{
                		sTemp = pTable->GetAt(t);
                		TRACE("\\n %s \\n",sTemp);
                	}
                }
                int nCount = m\_arrDump.GetSize();
                for(int i = 0;i < nCount;++i)delete m\_arrDump.GetAt(i);
                m\_arrDump.RemoveAll();
                
                TRACE("\\n m\_arrDump %d \\n",m\_arrDump.GetSize());
                
                CDocument::OnCloseDocument();
                

                }

                A 1 Reply Last reply
                0
                • M mesajflaviu

                  I don't know if is corect , but I think that I solve it :

                  // CMyDoc.h
                  typedef CTypedPtrArray CDumpArray;
                  class CMyDoc : public CDocument
                  {
                  protected: // create from serialization only
                  CMyDoc();
                  DECLARE_DYNCREATE(CMyDoc)

                  // Attributes
                  public:
                  CDumpArray m_arrDump;
                  ...
                  };

                  // CMyDoc.cpp
                  CString sText = "one";
                  CStringArray* pTable = NULL;
                  pTable = new CStringArray();
                  pTable->Add(sText);
                  sText = "two";
                  pTable->Add(sText);

                  m\_arrDump.Add(pTable);
                  
                  pTable = new CStringArray();
                  sText = "three";
                  pTable->Add(sText);
                  sText = "four";
                  pTable->Add(sText);
                  
                  m\_arrDump.Add(pTable);
                  

                  void CMyDoc::OnCloseDocument()
                  {
                  // TODO: Add your specialized code here and/or call the base class

                  TRACE("\\n m\_arrDump %d \\n",m\_arrDump.GetSize());
                  
                  CString sTemp;
                  for(int n = 0;n < m\_arrDump.GetSize();++n)
                  {
                  	TRACE("\\n StringArray no %d \\n",n);
                  	CStringArray\* pTable = m\_arrDump.GetAt(n);
                  	for(int t = 0;t < pTable->GetSize();++t)
                  	{
                  		sTemp = pTable->GetAt(t);
                  		TRACE("\\n %s \\n",sTemp);
                  	}
                  }
                  int nCount = m\_arrDump.GetSize();
                  for(int i = 0;i < nCount;++i)delete m\_arrDump.GetAt(i);
                  m\_arrDump.RemoveAll();
                  
                  TRACE("\\n m\_arrDump %d \\n",m\_arrDump.GetSize());
                  
                  CDocument::OnCloseDocument();
                  

                  }

                  A Offline
                  A Offline
                  Andrew Brock
                  wrote on last edited by
                  #8

                  I cant see anything wrong with this, however a better solution for CMyDoc::OnCloseDocument() would be

                  void CMyDoc::OnCloseDocument()
                  {
                  // TODO: Add your specialized code here and/or call the base class

                  TRACE("\\n m\_arrDump %d \\n",m\_arrDump.GetSize());
                  
                  CString sTemp;
                  int nCount = m\_arrDump.GetSize();
                  for(int n = 0;n < nCount; ++n)
                  {
                  	TRACE("\\n StringArray no %d \\n",n);
                  	CStringArray\* pTable = m\_arrDump.GetAt(n);
                  	for(int t = 0;t < pTable->GetSize();++t)
                  	{
                  		sTemp = pTable->GetAt(t);
                  		TRACE("\\n %s \\n",sTemp);
                  	}
                  	delete pTable; //You can delete these here for better code locality. You are only deleting the memory associated with them, not the item from the array.
                  }
                  //You dont need this next call unless you plan on reusing THIS instance of CMyDoc (which you shouldn't). CMyDoc::~CMyDoc() will clean it all up
                  m\_arrDump.RemoveAll(); //Remove all the (now invalid) items from the array
                  
                  CDocument::OnCloseDocument();
                  

                  }

                  M 1 Reply Last reply
                  0
                  • A Andrew Brock

                    I cant see anything wrong with this, however a better solution for CMyDoc::OnCloseDocument() would be

                    void CMyDoc::OnCloseDocument()
                    {
                    // TODO: Add your specialized code here and/or call the base class

                    TRACE("\\n m\_arrDump %d \\n",m\_arrDump.GetSize());
                    
                    CString sTemp;
                    int nCount = m\_arrDump.GetSize();
                    for(int n = 0;n < nCount; ++n)
                    {
                    	TRACE("\\n StringArray no %d \\n",n);
                    	CStringArray\* pTable = m\_arrDump.GetAt(n);
                    	for(int t = 0;t < pTable->GetSize();++t)
                    	{
                    		sTemp = pTable->GetAt(t);
                    		TRACE("\\n %s \\n",sTemp);
                    	}
                    	delete pTable; //You can delete these here for better code locality. You are only deleting the memory associated with them, not the item from the array.
                    }
                    //You dont need this next call unless you plan on reusing THIS instance of CMyDoc (which you shouldn't). CMyDoc::~CMyDoc() will clean it all up
                    m\_arrDump.RemoveAll(); //Remove all the (now invalid) items from the array
                    
                    CDocument::OnCloseDocument();
                    

                    }

                    M Offline
                    M Offline
                    mesajflaviu
                    wrote on last edited by
                    #9

                    Thanks , works fine ! Thank you all !!!

                    1 Reply Last reply
                    0
                    Reply
                    • Reply as topic
                    Log in to reply
                    • Oldest to Newest
                    • Newest to Oldest
                    • Most Votes


                    • Login

                    • Don't have an account? Register

                    • Login or register to search.
                    • First post
                      Last post
                    0
                    • Categories
                    • Recent
                    • Tags
                    • Popular
                    • World
                    • Users
                    • Groups