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. Corruption of the heap. Why ?

Corruption of the heap. Why ?

Scheduled Pinned Locked Moved C / C++ / MFC
helpquestiondata-structuresdebuggingperformance
10 Posts 4 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.
  • S Offline
    S Offline
    sdancer75
    wrote on last edited by
    #1

    Hi, I have a CFormView derived class named CCatalogView. The Dialog Form was designed using the VS2008 resource editor. I also created a new method inside the CCatalogView like the follow :

    CWnd* CCatalogView::CreatePane(CWnd* pParentWnd)
    {
    if (GetSafeHwnd() == 0){
    VERIFY(Create(_T("CatalogView"), NULL, WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, CXTPEmptyRect(), pParentWnd, NULL, 0));

    }
    return this;
    }

    While I can show the content of this FormView inside a pane, when I exit from the application I get a memory error : =================================== Windows has triggered a breakpoint in Test.exe. This may be due to a corruption of the heap, which indicates a bug in Test.exe or any of the DLLs it has loaded. This may also be due to the user pressing F12 while Test.exe has focus. The output window may have more diagnostic information. ==================================== I have already found a solution, and that was to use the

    create

    method, outside of the class CCatalogView as with the following code :

    m_pFormFrame = new CFrameWnd;
    CCreateContext context;
    context.m_pNewViewClass = RUNTIME_CLASS(CCatalogView);
    context.m_pCurrentDoc = NULL;

    m_pFormFrame->Create(NULL, NULL, WS_CHILD|WS_VISIBLE|WS_CLIPCHILDREN|WS_CLIPSIBLINGS, CRect(0, 0, 0, 0), this, NULL, 0, &context);
    m_pFormFrame->SendMessageToDescendants(WM_INITIALUPDATE, 0, 0, TRUE, TRUE);
    pPane->Attach(m_pFormFrame);

    Now the question is : Why the 1st part of the code corrupts the heap ? I suspect the the "Create" is constructed to the heap instead of the stack that I assume. If that is true, can I modify the code to make it work ? Best Regards,

    sdancer75

    R A 2 Replies Last reply
    0
    • S sdancer75

      Hi, I have a CFormView derived class named CCatalogView. The Dialog Form was designed using the VS2008 resource editor. I also created a new method inside the CCatalogView like the follow :

      CWnd* CCatalogView::CreatePane(CWnd* pParentWnd)
      {
      if (GetSafeHwnd() == 0){
      VERIFY(Create(_T("CatalogView"), NULL, WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, CXTPEmptyRect(), pParentWnd, NULL, 0));

      }
      return this;
      }

      While I can show the content of this FormView inside a pane, when I exit from the application I get a memory error : =================================== Windows has triggered a breakpoint in Test.exe. This may be due to a corruption of the heap, which indicates a bug in Test.exe or any of the DLLs it has loaded. This may also be due to the user pressing F12 while Test.exe has focus. The output window may have more diagnostic information. ==================================== I have already found a solution, and that was to use the

      create

      method, outside of the class CCatalogView as with the following code :

      m_pFormFrame = new CFrameWnd;
      CCreateContext context;
      context.m_pNewViewClass = RUNTIME_CLASS(CCatalogView);
      context.m_pCurrentDoc = NULL;

      m_pFormFrame->Create(NULL, NULL, WS_CHILD|WS_VISIBLE|WS_CLIPCHILDREN|WS_CLIPSIBLINGS, CRect(0, 0, 0, 0), this, NULL, 0, &context);
      m_pFormFrame->SendMessageToDescendants(WM_INITIALUPDATE, 0, 0, TRUE, TRUE);
      pPane->Attach(m_pFormFrame);

      Now the question is : Why the 1st part of the code corrupts the heap ? I suspect the the "Create" is constructed to the heap instead of the stack that I assume. If that is true, can I modify the code to make it work ? Best Regards,

      sdancer75

      R Offline
      R Offline
      Rolf Kristensen
      wrote on last edited by
      #2

      I can recommend using Application Verifier[^] and then run your application within a debugger. Then it should break the application at the initial corruption of the heap. Application Verifier is part of the Windows SDK[^]

      L S 2 Replies Last reply
      0
      • R Rolf Kristensen

        I can recommend using Application Verifier[^] and then run your application within a debugger. Then it should break the application at the initial corruption of the heap. Application Verifier is part of the Windows SDK[^]

        L Offline
        L Offline
        Lost User
        wrote on last edited by
        #3

        Yep, verifier, it is a good tool.

        ============================== Nothing to say.

        1 Reply Last reply
        0
        • S sdancer75

          Hi, I have a CFormView derived class named CCatalogView. The Dialog Form was designed using the VS2008 resource editor. I also created a new method inside the CCatalogView like the follow :

          CWnd* CCatalogView::CreatePane(CWnd* pParentWnd)
          {
          if (GetSafeHwnd() == 0){
          VERIFY(Create(_T("CatalogView"), NULL, WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, CXTPEmptyRect(), pParentWnd, NULL, 0));

          }
          return this;
          }

          While I can show the content of this FormView inside a pane, when I exit from the application I get a memory error : =================================== Windows has triggered a breakpoint in Test.exe. This may be due to a corruption of the heap, which indicates a bug in Test.exe or any of the DLLs it has loaded. This may also be due to the user pressing F12 while Test.exe has focus. The output window may have more diagnostic information. ==================================== I have already found a solution, and that was to use the

          create

          method, outside of the class CCatalogView as with the following code :

          m_pFormFrame = new CFrameWnd;
          CCreateContext context;
          context.m_pNewViewClass = RUNTIME_CLASS(CCatalogView);
          context.m_pCurrentDoc = NULL;

          m_pFormFrame->Create(NULL, NULL, WS_CHILD|WS_VISIBLE|WS_CLIPCHILDREN|WS_CLIPSIBLINGS, CRect(0, 0, 0, 0), this, NULL, 0, &context);
          m_pFormFrame->SendMessageToDescendants(WM_INITIALUPDATE, 0, 0, TRUE, TRUE);
          pPane->Attach(m_pFormFrame);

          Now the question is : Why the 1st part of the code corrupts the heap ? I suspect the the "Create" is constructed to the heap instead of the stack that I assume. If that is true, can I modify the code to make it work ? Best Regards,

          sdancer75

          A Offline
          A Offline
          Aescleal
          wrote on last edited by
          #4

          You're calling two completely different functions! In the first example you're calling CCatalogView::Create, in the second you're calling CFrameWnd::Create. As to why it's failing.. I can't tell exactly but one idea is that you're creating the CCatalogView as an automatic object. When you call CreatePane a WIN32 window object is created. When the pane window (as in the WIN32 window) is destroyed it tells the CCatalogView to do a delete this;. As the C++ object is on the stack delete goes a bit haywire. In the second case everything's allocated on the heap. You CCatalogView is implicitly created on the heap by CFrameWnd::Create. When the WIN32 window objects are destroyed the delete this; works the way it should do and everything's cool. Just out of interest all this delete this; rubbish generally happens in whatever override of CWnd::PostNCDestroy gets called. As a general rule always create MFC C++ window objects on the heap, unless it's a modal dialogue when it's safe to create it on the stack.

          S 2 Replies Last reply
          0
          • R Rolf Kristensen

            I can recommend using Application Verifier[^] and then run your application within a debugger. Then it should break the application at the initial corruption of the heap. Application Verifier is part of the Windows SDK[^]

            S Offline
            S Offline
            sdancer75
            wrote on last edited by
            #5

            Thanks, I didn't used Application Verifier before. Does it run under the VS2008 IDE ? Regards,

            sdancer75

            1 Reply Last reply
            0
            • A Aescleal

              You're calling two completely different functions! In the first example you're calling CCatalogView::Create, in the second you're calling CFrameWnd::Create. As to why it's failing.. I can't tell exactly but one idea is that you're creating the CCatalogView as an automatic object. When you call CreatePane a WIN32 window object is created. When the pane window (as in the WIN32 window) is destroyed it tells the CCatalogView to do a delete this;. As the C++ object is on the stack delete goes a bit haywire. In the second case everything's allocated on the heap. You CCatalogView is implicitly created on the heap by CFrameWnd::Create. When the WIN32 window objects are destroyed the delete this; works the way it should do and everything's cool. Just out of interest all this delete this; rubbish generally happens in whatever override of CWnd::PostNCDestroy gets called. As a general rule always create MFC C++ window objects on the heap, unless it's a modal dialogue when it's safe to create it on the stack.

              S Offline
              S Offline
              sdancer75
              wrote on last edited by
              #6

              Thank you for your reply. I am not sure if this is the real problem.... I will search more about this. Regards,

              sdancer75

              1 Reply Last reply
              0
              • A Aescleal

                You're calling two completely different functions! In the first example you're calling CCatalogView::Create, in the second you're calling CFrameWnd::Create. As to why it's failing.. I can't tell exactly but one idea is that you're creating the CCatalogView as an automatic object. When you call CreatePane a WIN32 window object is created. When the pane window (as in the WIN32 window) is destroyed it tells the CCatalogView to do a delete this;. As the C++ object is on the stack delete goes a bit haywire. In the second case everything's allocated on the heap. You CCatalogView is implicitly created on the heap by CFrameWnd::Create. When the WIN32 window objects are destroyed the delete this; works the way it should do and everything's cool. Just out of interest all this delete this; rubbish generally happens in whatever override of CWnd::PostNCDestroy gets called. As a general rule always create MFC C++ window objects on the heap, unless it's a modal dialogue when it's safe to create it on the stack.

                S Offline
                S Offline
                sdancer75
                wrote on last edited by
                #7

                As you can see "Call Stack" stops at _CrtIsValidHeapPointer. It seems that is trying to free the CCatalogView Object but it fails. Maybe that means that somehow the CCatalogView class has alreaded deleted from the memory. What is your opinion ? ntdll.dll!77470724() [Frames below may be incorrect and/or missing, no symbols loaded for ntdll.dll] ntdll.dll!7743295a() ntdll.dll!77401997() KernelBase.dll!760d4bf9() > Gnosis.exe!_CrtIsValidHeapPointer(const void * pUserData=0x03387e2c) Line 2103 C++ Gnosis.exe!_free_dbg_nolock(void * pUserData=0x03387e2c, int nBlockUse=12582916) Line 1317 + 0x9 bytes C++ Gnosis.exe!_free_dbg(void * pUserData=0x03387e2c, int nBlockUse=12582916) Line 1258 + 0xd bytes C++ Gnosis.exe!CObject::operator delete(void * p=0x03387e2c) Line 42 + 0xe bytes C++ Gnosis.exe!CCatalogView::`scalar deleting destructor'() + 0x3c bytes C++ Gnosis.exe!CView::PostNcDestroy() Line 121 + 0x21 bytes C++ Gnosis.exe!CWnd::OnNcDestroy() Line 864 C++ Gnosis.exe!CWnd::OnWndMsg(unsigned int message=130, unsigned int wParam=0, long lParam=0, long * pResult=0x0018e038) Line 2042 C++ Gnosis.exe!CWnd::WindowProc(unsigned int message=130, unsigned int wParam=0, long lParam=0) Line 1755 + 0x20 bytes C++ Gnosis.exe!AfxCallWndProc(CWnd * pWnd=0x03387e2c, HWND__ * hWnd=0x001906d6, unsigned int nMsg=130, unsigned int wParam=0, long lParam=0) Line 240 + 0x1c bytes C++ Gnosis.exe!AfxWndProc(HWND__ * hWnd=0x001906d6, unsigned int nMsg=130, unsigned int wParam=0, long lParam=0) Line 403 C++ user32.dll!76126238() user32.dll!76127298() user32.dll!76126899() user32.dll!76127177() user32.dll!76131e3a() ntdll.dll!773b00e6() user32.dll!76131e83() Gnosis.exe!CWnd::DestroyWindow() Line 1007 + 0xd bytes C++ b60f0004()

                sdancer75

                A 1 Reply Last reply
                0
                • S sdancer75

                  As you can see "Call Stack" stops at _CrtIsValidHeapPointer. It seems that is trying to free the CCatalogView Object but it fails. Maybe that means that somehow the CCatalogView class has alreaded deleted from the memory. What is your opinion ? ntdll.dll!77470724() [Frames below may be incorrect and/or missing, no symbols loaded for ntdll.dll] ntdll.dll!7743295a() ntdll.dll!77401997() KernelBase.dll!760d4bf9() > Gnosis.exe!_CrtIsValidHeapPointer(const void * pUserData=0x03387e2c) Line 2103 C++ Gnosis.exe!_free_dbg_nolock(void * pUserData=0x03387e2c, int nBlockUse=12582916) Line 1317 + 0x9 bytes C++ Gnosis.exe!_free_dbg(void * pUserData=0x03387e2c, int nBlockUse=12582916) Line 1258 + 0xd bytes C++ Gnosis.exe!CObject::operator delete(void * p=0x03387e2c) Line 42 + 0xe bytes C++ Gnosis.exe!CCatalogView::`scalar deleting destructor'() + 0x3c bytes C++ Gnosis.exe!CView::PostNcDestroy() Line 121 + 0x21 bytes C++ Gnosis.exe!CWnd::OnNcDestroy() Line 864 C++ Gnosis.exe!CWnd::OnWndMsg(unsigned int message=130, unsigned int wParam=0, long lParam=0, long * pResult=0x0018e038) Line 2042 C++ Gnosis.exe!CWnd::WindowProc(unsigned int message=130, unsigned int wParam=0, long lParam=0) Line 1755 + 0x20 bytes C++ Gnosis.exe!AfxCallWndProc(CWnd * pWnd=0x03387e2c, HWND__ * hWnd=0x001906d6, unsigned int nMsg=130, unsigned int wParam=0, long lParam=0) Line 240 + 0x1c bytes C++ Gnosis.exe!AfxWndProc(HWND__ * hWnd=0x001906d6, unsigned int nMsg=130, unsigned int wParam=0, long lParam=0) Line 403 C++ user32.dll!76126238() user32.dll!76127298() user32.dll!76126899() user32.dll!76127177() user32.dll!76131e3a() ntdll.dll!773b00e6() user32.dll!76131e83() Gnosis.exe!CWnd::DestroyWindow() Line 1007 + 0xd bytes C++ b60f0004()

                  sdancer75

                  A Offline
                  A Offline
                  Aescleal
                  wrote on last edited by
                  #8

                  Either you've stuck the CCatalogView on the stack and PostNcDestroy is trying to delete it when the WIN32 window is being deleted OR you're stashing a pointer to the CCatalogView some where and deleting it. It may be hidden if you've stored it as a pointer to one of it's parent classes.

                  S 1 Reply Last reply
                  0
                  • A Aescleal

                    Either you've stuck the CCatalogView on the stack and PostNcDestroy is trying to delete it when the WIN32 window is being deleted OR you're stashing a pointer to the CCatalogView some where and deleting it. It may be hidden if you've stored it as a pointer to one of it's parent classes.

                    S Offline
                    S Offline
                    sdancer75
                    wrote on last edited by
                    #9

                    Thank you Aescleal, Yes the CCatalogView is created on the stack and I did know that from the beggining, but I was wondering about the time are happenning all these things.

                    1. I create on the stack the CCatalogView

                    1. Inside the CCatalogView class I create a Win32 Window (using Create). Really, does this window is created on the heap or in the stack ? I assume that is created on the stack. Anyway, I tried to explicitly create this window on the heap, using new (on the CreatePane) & delete (on the destructor) functions but it also fails.

                    2. Now, according to my assumptions that both objects are in the stack, at the exiting procedure, it disposes first the last inserted item which is the Win32 Window (as I mentioned, I assume it created on the stack) and then the CCatalogView class itleft.

                    What's of the above assumptions are wrong ? That is what I did not understand. Regards, George PS: Reading your comment again, you assume that the MFC Framework when is trying to delete the Window itself, is deleting also the class that is associated with that window. Maybe, is something that I did not understand well. Can you please clarify that ?

                    sdancer75

                    S 1 Reply Last reply
                    0
                    • S sdancer75

                      Thank you Aescleal, Yes the CCatalogView is created on the stack and I did know that from the beggining, but I was wondering about the time are happenning all these things.

                      1. I create on the stack the CCatalogView

                      1. Inside the CCatalogView class I create a Win32 Window (using Create). Really, does this window is created on the heap or in the stack ? I assume that is created on the stack. Anyway, I tried to explicitly create this window on the heap, using new (on the CreatePane) & delete (on the destructor) functions but it also fails.

                      2. Now, according to my assumptions that both objects are in the stack, at the exiting procedure, it disposes first the last inserted item which is the Win32 Window (as I mentioned, I assume it created on the stack) and then the CCatalogView class itleft.

                      What's of the above assumptions are wrong ? That is what I did not understand. Regards, George PS: Reading your comment again, you assume that the MFC Framework when is trying to delete the Window itself, is deleting also the class that is associated with that window. Maybe, is something that I did not understand well. Can you please clarify that ?

                      sdancer75

                      S Offline
                      S Offline
                      sdancer75
                      wrote on last edited by
                      #10

                      Ok, I found the cause of the problem. The default for views is to allocate them on the heap and the default post-cleanup is to 'delete this'. So, in my situation I created the window in the stack, like it shows below.

                      VERIFY(Create(_T("MyWind"), NULL, WS_CHILD | WS_VISIBLE, CXTPEmptyRect(), pParentWnd, IDD_TABSHEET2, &context));

                      The default behavior of the CView cleanup is to delete this. Indeed, if you check inside the viewcore.cpp you will see, something like this :

                      // self destruction
                      void CView::PostNcDestroy()
                      {
                      // default for views is to allocate them on the heap
                      // the default post-cleanup is to 'delete this'.
                      // never explicitly call 'delete' on a view
                      delete this;
                      }

                      That thing is all screwed up in my case. The solution ? Just override the CCatalogView::PostNcDestroy and comment the CFormView::PostNcDestroy(); to prevent calling the CView::PostNcDestroy.

                      void CCatalogView::PostNcDestroy()
                      {
                      // TODO: Add your specialized code here and/or call the base class
                      _ASSERTE( _CrtCheckMemory( ) );

                      //Don't call default PostNCDestroy which it calls CView:: delete this
                      //because you get a heap corruption since the view is created on the stack.
                      //CFormView::PostNcDestroy();
                      

                      }

                      Hope, it helps someone. Regards,

                      sdancer75

                      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