CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 1 of 2 12 LastLast
Results 1 to 15 of 20
  1. #1
    Join Date
    Jan 2007
    Location
    Italy
    Posts
    156

    [RESOLVED] exit(): memory leaks?

    I built a pointer based class, that makes a lot of use of dynamic memory allocation with new. So I equipped the class with an appropriate destructor, that traces back all allocated objects and deletes them.

    The problem is: if in some point of my application I use exit() or _exit() to abruptly terminate the app in response to an invalid capital operation of the user, the destructor is never called; does the memory that my classes have allocated get deallocated in the exit() routine? I use a lot of new, so if memory does not get correctly deallocated I fear some system memory shortage if the app is launched and closed with exit more than once...

    Is exit() to be avoided in these cases?

    Thanks in advance
    - Buzzyous -

  2. #2
    VictorN's Avatar
    VictorN is online now Super Moderator Power Poster
    Join Date
    Jan 2003
    Location
    Hanover Germany
    Posts
    20,398

    Re: exit(): memory leaks?

    If your application is not a console one but a Win32 then you must not use exit() to exit.
    Victor Nijegorodov

  3. #3
    Join Date
    Apr 1999
    Posts
    27,449

    Re: exit(): memory leaks?

    Quote Originally Posted by Buzzyous View Post
    I built a pointer based class, that makes a lot of use of dynamic memory allocation with new. So I equipped the class with an appropriate destructor, that traces back all allocated objects and deletes them.

    The problem is: if in some point of my application I use exit() or _exit() to abruptly terminate the app in response to an invalid capital operation of the user, the destructor is never called
    Which is what happens when you call exit(). Why are you calling exit() and where do you call it? Your program has undefined behaviour depending on when and where this function is called, and what type of app (GUI or console). You need to either properly terminate your application by returning to the main()/WinMain() function, or register an atexit() function that cleans up the memory (for console apps).

    As to your question, the memory is returned after the process is terminated. This is the case for any application. So technically, you still have a memory leak, with the only saving grace being that the OS cleans up memory allocated by the system automatically.
    I use a lot of new, so if memory does not get correctly deallocated I fear some system memory shortage if the app is launched and closed with exit more than once...
    If you were writing for another OS that does not automatically return the memory back to the system on process termination, then you would have a problem. Fortunately, a 32/64 bit Windows OS reclaims memory on process termination.

    However, you should fix your program to make sure that the memory is destroyed. The reason is that you don't know when that routine will be moved to another part of your application, where it will matter if the memory is cleaned up or not (for example, you're calling the function in a loop). Also, third-party memory checking tools will always report a memory leak if you don't clean up the memory, even on program termination.

    Regards,

    Paul McKenzie

  4. #4
    Join Date
    Jan 2007
    Location
    Italy
    Posts
    156

    Re: exit(): memory leaks?

    I'm writing a Win application. In a dialog window the user has to insert some data. If these data refers to a bad, corrupted or mismatching file the application needs to close (after propting the user) to prevent user from accessing a support he doesn't need to. So I call exit(), but, reading what you say, I think I won't use it anymore, and I'll terminate the app in some other way, like as you say using atexit(), which was what I was looking for but I didn't know it.

    Thank you all.
    - Buzzyous -

  5. #5
    Join Date
    Apr 1999
    Posts
    27,449

    Re: exit(): memory leaks?

    Quote Originally Posted by Buzzyous View Post
    I'm writing a Win application. In a dialog window the user has to insert some data. If these data refers to a bad, corrupted or mismatching file the application needs to close (after propting the user) to prevent user from accessing a support he doesn't need to. So I call exit(),
    Pretend exit() doesn't exist! What would you do in that case? I have never written an application that needed to call exit(), and many here have never needed to use exit() for far more complex applications that need to close down for some reason.
    I'll terminate the app in some other way,
    Close the dialog, have the dialog return a "get out now" return value, and then the invoker of the dialog (whomever that is), takes this return code and terminates the app correctly and normally. There is no need to pull the rug out from under the entire program by calling exit() abruptly. As a matter of fact, I'm suspicious of any program, unless it is a low-level 'C' program, calling exit().

    Regards,

    Paul McKenzie
    Last edited by Paul McKenzie; February 8th, 2009 at 01:08 PM.

  6. #6
    Join Date
    Jan 2007
    Location
    Italy
    Posts
    156

    Re: exit(): memory leaks?

    Quote Originally Posted by Paul McKenzie View Post
    Close the dialog, have the dialog return a "get out now" return value, and then the invoker of the dialog (whomever that is), takes this return code and terminates the app correctly and normally.
    I defined PREMATURE_EXIT as -55. The invoker of the CDialog is a CWiew class.
    Now, the CDialog has some children CWnd that has new allocated memory too. I wrote this:

    Code:
    //In the CDialog derived class
    		EndDialog(PREMATURE_EXIT);     //Closes the dialog returning -55
    
    //In the CWiew invoker
    	if (init.DoModal()==PREMATURE_EXIT)
    	{
                     AfxGetMainWnd()->SendMessage(WM_CLOSE,MAKEWPARAM(-55,0));
    	}
    So, I think this is a normal and legitmate program terminating way. Yet, still, I can't get the destructors of the children of the CDialog get called, nor I can intercept in any way their WM_CLOSE messages...
    If I call directly their destructor retrieving the members of the dialog, or call the destructor of the dialog, the child gets deleted, but the i get a violation access error, inside the child destructor code, because this gets called twice...

    So, if I let the framework alone, it will exit from the app without deallocating the children, but if I force him to call the destructor, it calls them twice.
    I think this is due to the fact that the destructors are called automatically when the invoker of the dialog exits its current function (a message handler), but if I exit closing the main window the app gets closed skipping that part, leaving my memory allocated.

    So, what can I do in order to exit AND call destructors of children of my CDialog derived class?

    I am really puzzled
    Last edited by Buzzyous; February 9th, 2009 at 11:50 AM.
    - Buzzyous -

  7. #7
    Join Date
    Apr 1999
    Posts
    27,449

    Re: exit(): memory leaks?

    Quote Originally Posted by Buzzyous View Post
    I think this is due to the fact that the destructors are called automatically when the invoker of the dialog exits its current function (a message handler), but if I exit closing the main window the app gets closed skipping that part, leaving my memory allocated.
    What evidence do you have that the destructors are not called?
    Code:
    class MyDialog : public CDialog
    {
    //...
           ~MyDialog() { OutputDebugString("Destructor called"); }
    };
    If the string "Destructor called" shows up in the OutputWindow, then the destructor is being called.

    Regards,

    Paul McKenzie

  8. #8
    Join Date
    Jan 2007
    Location
    Italy
    Posts
    156

    Re: [RESOLVED] exit(): memory leaks?

    Actually, to be very sure, I inserted in the destructor code an AfxMessageBox("Destructing") troubleshooting message... It is not shown, so I supposed destructors weren't called.
    Moreover, if I execute my app under debug it works... but if I launch withot debugging (CTRL+F5), it doesn't work twice in a row after exiting... So, something has gone REALLY wrong with all theese memory new things...
    - Buzzyous -

  9. #9
    Join Date
    Apr 1999
    Posts
    27,449

    Re: [RESOLVED] exit(): memory leaks?

    Quote Originally Posted by Buzzyous View Post
    Actually, to be very sure, I inserted in the destructor code an AfxMessageBox("Destructing") troubleshooting message... It is not shown, so I supposed destructors weren't called.
    No! Do not use Message Boxes to show debugging messages.

    The reason is simple -- what happens if the GUI is already closed, but the app is still running? How are you going to show a message box? Use the proper tools, and that is using OutputDebugString or trace logging, and never GUI components to show this information.

    Regards,

    Paul McKenzie

  10. #10
    Join Date
    Apr 1999
    Posts
    27,449

    Re: [RESOLVED] exit(): memory leaks?

    To be more blunt, you should never use message box to show you trace information. There will be that odd time where the message box will not display due to various reasons (threading, GUI shut down, some other thing gets thrown off in your app by the showing of the message box, etc).

    That odd time can cause you to lose a lot of energy and time thinking that there is something wrong with your app when there really is nothing wrong with it.

    Regards,

    Paul McKenzie

  11. #11
    Join Date
    Jan 2007
    Location
    Italy
    Posts
    156

    Re: [RESOLVED] exit(): memory leaks?

    I solved many issues, but still remain a problem; I got memory leaks for each object I allocate with new durinig the program. Even when destructor is called. So, I found out how to call destructors when needed, but the destructor doesn't work; I defined a structure, with a pointer to the same structure type that form up a list.
    The destructor just need to run over all members of the struct list (created with new) and delete its new-allocated pointer members and finally the pointer to the stuct itself. And it does, but still remains 48 byte memory leak per object, said normal block in the debugger...

    Can anybody help me out with this also?

    May be structs cannot be allocated and deallocated with new/delete?
    Last edited by Buzzyous; February 9th, 2009 at 04:47 PM.
    - Buzzyous -

  12. #12
    Join Date
    Apr 1999
    Posts
    27,449

    Re: [RESOLVED] exit(): memory leaks?

    Quote Originally Posted by Buzzyous View Post
    I solved many issues, but still remain a problem; I got memory leaks for each object I allocate with new durinig the program. Even when destructor is called.
    There is something seriously wrong with your program, or you are not doing something correctly. Without seeing the actual code, no one can help except to tell you to "be more careful".

    You also didn't respond to my previous post. Is that message printed to the Output Window? If it is, then there is nothing wrong with the destructor being called. Whether there is something else wrong with your program that causes problems when the destructors are invoked, then that is a different issue altogether.
    So, I found out how to call destructors when needed,
    And how do you do that? Destructors should be invoked automatically when either the object is

    1) an object created automatically, and it is destroyed by going out of scope
    2) The object was created dynamically, and and the destructor is called using "delete"
    3) The object is global, and the runtime (at some point after main()) cleans up the global object.

    There is no reason to be calling destructors explicitly, unless you're using placement-new, which I know you're not using.

    Also, the memory checker probably doesn't detect global objects being destroyed. Are you using global variables?

    Regards,

    Paul McKenzie

  13. #13
    Join Date
    Jan 2007
    Location
    Italy
    Posts
    156

    Re: [RESOLVED] exit(): memory leaks?

    I inserted many deb messages throughout the app.

    Before my last post, the message in the debug weren't called, because I closed the app without catching properly WM_CLOSE messages, and so on. Now I overrided virtuals like DestroyWindow(), that allow me to do appropriate destruction before closing the windows.

    Of course, as you know, no new placement, so no destructor direct calls, but delete calls, wich, however, calls destructors. So I get my "Destructor called" in the debug window. This is called now.

    Before, the app crashed because the destructors weren't called, I still didn't know that they malfunctioned.

    Now, destructors are called, and the program works, but has memory leaks because now I know that destructor isn't working correctly. So now the attention is posed over their deallocation process. The structs element of my list are defined as follows:

    Code:
    	struct myStr
    	{
    		SomeCustomClass* cst;
    		myStr* next;
    		CString identifier;
    		BOOL enabled;
    		CRect rect;
    	};
    These elemnts are dynamically created with new, and linked each other throug the next pointer, which of course points to the next element of the list.

    The creation phase:

    Code:
    //Adding new list element, appending to the bottom. LastEl is the current last myStr in the list
    
    myStr* newEl = new myStr;
    myStr->cst = new SomeCustomClass;
    //Other initialization, no more news
    Destruction phase, in the destructor of the class that contains the list:

    Code:
    	int pos=0;
    	//Destructing created objects
    	myStr *tmp, *ind=First;    //First is the first element in the list
    	while(ind)
    	{
    		tmp=ind;
    		ind=ind->next;
    		delete tmp->cst;
    		delete tmp;
    		pos++;
    	}
    	CString trouble;
            trouble.Format("Destructor called; %d elements destroyed\n",pos);
    	OutputDebugString(trouble);
    The debug windows confirm the correct number of elements destroyed, but, as I said, every element lefts behind a memory leak of 48 normal block bytes...
    Last edited by Buzzyous; February 9th, 2009 at 05:11 PM.
    - Buzzyous -

  14. #14
    Join Date
    Jan 2007
    Location
    Italy
    Posts
    156

    Re: [RESOLVED] exit(): memory leaks?

    Doesn't matter... Feels like I'll have to rewrite some code: not quite sure is what I shown the source of the leaks. Thank anyway, the help was really precious.
    - Buzzyous -

  15. #15
    Join Date
    May 2007
    Posts
    811

    Re: [RESOLVED] exit(): memory leaks?

    I see that you are using raw pointers and manual memory management, you know that c++ (stl and boost) provide helper classes to make this FAR easier.
    auto_ptr and here. Also boost has shared_ptr. Just learning those concepts alone will go a long way to write cleaner and mostly bug free applications.

Page 1 of 2 12 LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured