[RESOLVED Thanks] when is the destructor called ?
Quick question
When is a destructor called ?
Code:
ThreadManager::~ThreadManager()
{
CloseHandle(m_hThread);
};
Let's say this was in my code ?
Is the destructor called if this object goes out of scope ?
Example
void foo()
{
ThreadManager t ;
};
Is the destructor called when the scope has ended ?
Is there a way to call the destructor explicitly ?
Is it just as simple as delete t;
Thanks
Stev
Re: when is the destructor called ?
Quote:
Originally Posted by stephenprogrammer07
Quick question
When is a destructor called ?
When an object is destroyed.
Quote:
Is the destructor called if this object goes out of scope ?
Yes.
Quote:
Is there a way to call the destructor explicitly ?
Why? The object is automatically destroyed, so all you would be doing is destroying the same thing twice, causing program corruption.
Quote:
Is it just as simple as delete t;
You only call "delete" on objects that were created with "new".
http://www.parashift.com/c++-faq-lite/dtors.html
Regards,
Paul McKenzie
Re: when is the destructor called ?
yes the destructor is called whenever the variable goes out of scope, as in
Code:
#include <iostream>
using namespace std;
class one
{
int* a;
public:
one();
~one();
};
one::one()
{
a = new int;
*a = 5;
}
one::~one()
{
cout << "destructer called\n";
delete a;
}
int main()
{
{
one cur;
}
system("pause");
return 0;
}
shows you how it is called, you need a destructor to return stuff to the heap, it is called when the program exits unless the variable goes out of scope before hand
Re: when is the destructor called ?
You're right, the destructor is called when the object goes out of scope. However this is only for stack objects (objects that aren't created with new). For heap objects (objects that ARE created with new) the destructor is called when you delete the object.
To explicitly call a destructor somewhat removes the purpose of the destructor, since the idea behind having a destructor is that it is automatically called when the object is destroyed.
If you want to destroy an object before it goes out of scope, you can use your own destroy member function:
Code:
class Bla{
void CleanUp(); //the "destructor"
};
When you want to destroy the object, you call CleanUp(). If you want CleanUp() to automatically be called when the object goes out of scope or is deleted, call it from the destructor:
Code:
Bla::~Bla(){
CleanUp();
}
Hope this helps.
Re: when is the destructor called ?
Thanks I passed around some rep points for those answers.
Now I have something to add to this mix.
Here's my code
Code:
int main()
{
ThreadManager tmanager;
while(true)
{
if(tmanager.isThreadFinishedStatus() )
{
tmanager.launchThread(&threadManager);
}
}
}
As you can see here the ThreadManager never goes out of scope because this is an infinite while loop.
yet I put a print statement at the destructor and the destructor is called sure enough after the ThreadFunc finish running.
Isn't that something.
So since the destructor is called when my while loop executes tmanager.lanchThread(&threadManager); again, the application crashes because the destructor was called - even though the object did not go out of scope.
Any explanations on why destructor is called and app does not go out of scope ???
Thanks in advance
stev
Below is my ThreadManager code
Code:
ThreadManager::ThreadManager()
{
m_dwThreadID = 0 ;
m_hThread = 0 ;
threadStatus = true;
};
ThreadManager::~ThreadManager()
{
CloseHandle(m_hThread);
prinf("aha destructor does call before going out of scope " ) ;
};
bool ThreadManager::hasThreadReturned()
{
return threadStatus;
};
void ThreadManager::setThreadFinishedStatus(bool s )
{
if(s)
{
printf("\nThreadManager::setThreadFinishedStatus set to
true\n");
}else
printf("\nThreadManager::setThreadFinishedStatus set to
false\n");
threadStatus = s;
};
bool ThreadManager::launchThread(ThreadManager *whatever)
{
m_hThread = CreateThread(0,
0,
ThreadFunc,
(void *)whatever,
0,
&m_dwThreadID);
if(!m_hThread)
{
return false;
}
return true;
};
HANDLE ThreadManager::TheHandle(void) const { return m_hThread;
};
DWORD WINAPI ThreadManager::ThreadFunc(LPVOID pvParam)
{
Speech sp ;
ThreadManager* t = (ThreadManager*) pvParam;
t->setThreadFinishedStatus(false );
sp.Create("this is a sample param passed in") ;
::WaitForSingleObject(sp.TheHandle(), INFINITE );
t->setThreadFinishedStatus(true );
};
Speech sp is another Thread that takes bit of time to run.
Re: when is the destructor called ?
First, RAII and other design patterns that depend upon a strong constructor/destructor cycle would utterly fail if a destructor is called for any other reasons that an object's deletion (falling out of scope, delete, etc).
Under normal circumstances, it doesn't happen - destructors aren't called outside the described circumstance - that is, since you're getting a 'destructor message' even though you say the execution point is still inside the while loop, something else is responsible.
Can you produce a stack trace at that moment? It would be most instructive.
I have encountered situations where stack corruptions happen to be such that a function is called that should not be.
RESOLVED: when is the destructor called ?
@JVene
I don't know how to do a stack trace.
I'll have to figure out how to produce a stacktrace in c++.
I'm studying this article on the topic http://www.ddj.com/184405270?pgno=1
Is that a good way or do you have another way to get the stack trace ? I'm using Dev C++.
----------------------------------
Additionally, I conducted a few tests.
1. I made 2 very simple thread classes demonstrate that in truth one Thread , launching another Thread who's destructor is called will not automatically call the launching Threads destructor. I confirmed that.
2. So I tested my own code a bit more. For some reason when my thread simply instantiates my Speech class "Speech sp; in DWORD WINAPI ThreadFunc " as soon as sp goes out of Scope (meaning DWORD WINAPI ThreadFunc is finished), it calls Speech's destructor as expected but for some reason it also calls the destructor of the Launching thread which is not supposed to be called.
If I comment out Speech sp , the launching Thread's destructor is not calle.d everything works as expected
So that's where I am with it .
UPDATE:
WOOPS Never mind .
Now I see why the Launching Thread's destructor was called.
It turns out that my Speech class had as a private member The Launching Thread class.
So naturally when the speech class went out of scope it also called the destructor on the private member. So I was confused a by that.
The launching Thread's destructor was not really being called.
The private member of the speech was called.
NEVER MIND I'VE GOT IT PROBLEM RESOLVED.
Stephen
Re: RESOLVED: when is the destructor called ?
Quote:
Originally Posted by stephenprogrammer07
NEVER MIND I'VE GOT IT PROBLEM RESOLVED.
I take it that the race conditions, the busy-wait loop and the inability of the program to terminate cleanly are not an issue.
Re: [RESOLVED Thanks] when is the destructor called ?
Quote:
Originally Posted by stephenprogrammer07
Quick question
When is a destructor called ?
Code:
ThreadManager::~ThreadManager()
{
CloseHandle(m_hThread);
};
Let's say this was in my code.
Is the destructor called if this object goes out of scope ?
Yes it will.
Quote:
Example
Code:
void foo()
{
ThreadManager t ;
}
Is the destructor called when the scope has ended ?
In this case it will indeed be. Therefore you may have to ensure that CloseHandle is a valid call here - that m_hThread requires closing.
Quote:
Is there a way to call the destructor explicitly ?
Yes, calling ~ThreadManager() is allowed but should be used only when the object was created with placement-new. Placement-new is a special way to create an object whereby the constructor is called but no memory is allocated. Instead you indicate where to construct the object. It is often done in conjunction with memory-pooling. std::vector uses it as well because here you create multiple objects in a contiguous memory block.
Quote:
Is it just as simple as delete t;
That will invoke ~ThreadManager but should be called only on a pointer created with regular new. It will also release the memory.
Re: [RESOLVED Thanks] when is the destructor called ?
Quote:
Originally Posted by stephenprogrammer07
Quick question
When is a destructor called ?
Code:
ThreadManager::~ThreadManager()
{
CloseHandle(m_hThread);
};
Let's say this was in my code ?
Is the destructor called if this object goes out of scope ?
Example
void foo()
{
ThreadManager t ;
};
Is the destructor called when the scope has ended ?
Is there a way to call the destructor explicitly ?
Is it just as simple as delete t;
Thanks
Stev
If the class of an object has a destructor, C++ guarantees that the destructor is called when the object dies. A local (auto) object dies at the close of the block ({...}) in which it was created (that is, when it is conceptually popped from the runtime stack). An unbound temporary object dies at the end of the outermost expression in which the temporary was generated (often this is at the next ; ). A member object dies when its containing object dies. An array element dies when its array dies. An object allocated via new (dynamically) dies when the object is deleted. With a static object, death occurs sometime after main() finishes.
Everything but dynamically allocated objects (that is, local objects, temporary objects, member objects, static objects, and array elements) are destructed in the reverse order of construction: first constructed is last destructed.
Re: RESOLVED: when is the destructor called ?
Quote:
Originally Posted by googler
I take it that the race conditions, the busy-wait loop and the inability of the program to terminate cleanly are not an issue.
thanks everyone points given all around
@googler
what is the alternative to the busy wait that you are suggesting ?
Re: RESOLVED: when is the destructor called ?
Quote:
Originally Posted by stephenprogrammer07
what is the alternative to the busy wait that you are suggesting ?
In the main loop, use WaitForSingleObject() to wait on the thread handle. A wait on a thread handle terminates when the thread terminates and doesn't take up CPU cycles.
The code #5 also has a pretty serious race condition, because the flag threadStatus is set to false by the newly launched thread. That means the loop in main can execute an arbitrary number of iterations before the new thread sets the flag to false, and each iteration launches another thread before the first thread even starts. Each time a new thread is launched like this, it overwrites the thread handle thereby orphaning the previous threads it launched and leaving an unclosed handle.
Bottom line is that you shouldn't use a boolean to signal termination of a thread. The best thing to do is wait on the thread handle. A slightly less attractive solution is for the thread to use an Event object to signal its termination right before it exits, and then have main wait on the Event.
The final problem is that there is no way to signal main to exit its loop. This means it can only be terminated by killing its thread or the entire process (from another thread.) Killing the entire process isn't so bad because Windows cleans up the mess you left behind, but killing threads with TerminateThread (as opposed to letting the thread exit) generally leaves behind some memory and resource leaks.
It's sometimes necessary to kill threads or processes, but when you design the program, you should generally design a way to get each thread to exit gracefully. In your code there is no way for main to exit gracefully.
Re: when is the destructor called ?
Quote:
Originally Posted by googler
In the main loop, use WaitForSingleObject() to wait on the thread handle. A wait on a thread handle terminates when the thread terminates and doesn't take up CPU cycles.
My application has a GUI (code #5 is just stripped down). My goal was to provide onscreen animation and user interaction with the GUI while this thread is running.
If I used WaitForSingleObject() in the main loop, my GUI would freeze until the thread returned. I tested it to confirm that.
The reason that I created a new thread which launches the thread of interest was with the goal of maintaining the GUI interactivity.
So it doesn't seem that WaitForSingleObject() in main loop would work for my purpose unless it canwork otherwise.
Quote:
That means the loop in main can execute an arbitrary number of iterations before the new thread sets the flag to false,
making the main loop ::Sleep(10) after the launch is a crude way to fix that problem . But I admit it's a crude way to prevent race conditions.
my app is a game which normally has a indefinite while loop until the player ends the game. I use the while loop to mimic the game loop.
But if this were a normal application, I guess I would have to try something like the observer pattern or figure out how to use mutex and locks to block all threads creating new code until the other thread drops the lock.
Re: when is the destructor called ?
Quote:
Originally Posted by stephenprogrammer07
My application has a GUI (code #5 is just stripped down). My goal was to provide onscreen animation and user interaction with the GUI while this thread is running.
There are two more reasonable ways to combine a GUI message loop with waiting for background threads to finish
1) Have main execute a standard message loop. Have the background thread post a special user-defined Window message to the GUI thread (with PostMesssage) right before it terminates. Receipt of this message is the signal that the background thread is complete. With this approach you don't need any additional synchronization objects.
2) Use MsgWaitForMultipleObjects/MsgWaitForMultipleObjectsEx. This is a general mechanism for combining a GUI message loop with waiting on any number of kernel handles of any kind. The wait completes when a GUI message is ready to process or any of the handles is signalled. The program can tell from the return value why the wait completed, handle the event that caused the completion (be it a GUI message or thread terminating) and then loop to another call to the same wait function. The message loop will be terminated in response to the usual WM_QUIT message.
Re: when is the destructor called ?
would you be willing to provide a code sample of each ? .
And just to confirm - those solutions will not block the main thread until they are finished right ?
Stephen
Re: when is the destructor called ?
Your thread can post a message to the GUI's main window when it is about to close.
Note also that there is a WaitForSingleObjectEx call that allows QueueUserAPC calls. QueueUserAPC allows threads to actually queue function-calls which will be called in order when the thread reaches an idle state.
This actually makes a very good messaging system. I usually use a standard APC function which is made typesafe using an abstract base class which is cast then cast back and then its method gets called. You then call the pointer's release() method when you've finished with it. The downside is that when the thread is closing it has to purge its queue to avoid memory leaks.
Re: when is the destructor called ?
I never studied multi-threading in c++ before.
I'll go down to the book store and look at a few books.
But would you happen to have a simple code sample which demonstrates what you are sharing.
Stephen
Re: when is the destructor called ?
Quote:
Originally Posted by stephenprogrammer07
would you be willing to provide a code sample of each ? .
Do you want code samples that demonstrate multi threading in GUI for
game programming? Follow this link
http://www.ogre3d.org/
Re: when is the destructor called ?
maybe i found a good example of proper multhreaded programming at http://www.relisoft.com/win32/active.html
let me know if anyone else knows of a great tutorial.
Re: when is the destructor called ?
Here's how to use MsgWaitForMultipleObjects to do the loop in main
Code:
#define NUM_THREADS 1
int __stdcall WinMain(
HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
/*
* set up GUI here
*/
ThreadManager tmanager;
/*
* Launch first thread
*/
tmanager.launchThread(&tmanager);
/*
* The message loop lasts until we get a WM_QUIT message,
* upon which we shall return from main.
*/
while (true)
{
MSG msg;
bool wmQuit = false;
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
// If it is a quit message, exit.
if (msg.message == WM_QUIT) {
wmQuit = true;
break;
}
TranslateMessage(&msg);
DispatchMessage(&msg);
}
if (wmQuit)
break;
HANDLE handles[NUM_THREADS];
handles[0] = tmanager.TheHandle();
if (handles[0] == NULL) {
WaitMessage();
continue;
}
DWORD result = MsgWaitForMultipleObjects(
NUM_THREADS,
&handles[0],
FALSE,
INFINITE,
QS_ALLINPUT);
if (result == (WAIT_OBJECT_0 + NUM_THREADS)) {
// New messages have arrived.
continue;
} else {
// Thread has completed
tmanager.close();
tmanager.launchThread(&tmanager);
}
}
tmanager.shuttingDown();
return 0;
}
Re: when is the destructor called ?
Thanks I really appreciate the code example.
This looks a lot simpler than all the classes I had to make to get Mutex and Locks working. I'm studying it.
By the way, in my threadmanager class I didn't have
close()
shuttingdown()
what kind of code did you envison in close() and shuttingDown()
Thanks
Stephen
Re: when is the destructor called ?
Quote:
Originally Posted by stephenprogrammer07
what kind of code did you envison in close() and shuttingDown()
Code:
ThreadManager::~ThreadManager()
{
if (m_hThread != NULL)
CloseHandle(m_hThread);
};
void ThreadManager::close()
{
if (m_hThread != NULL) {
CloseHandle(m_hThread);
m_hThread = NULL;
}
}
void ThreadManager::shuttingDown()
{
if (m_hThread != NULL) {
/*
* If you create an alternate mechanism for cleanly
* shutting down the thread, use it instead of TerminateThread
*/
TerminateThread(m_hThread, 0);
/*
* wait for it to finish, but not forever
* (this isn't really necessary with TerminateThread, but with
* a clean shutdown mechanism, wait for it)
*/
WaitForSingleObject(m_hThread, 10000);
}
}
Re: when is the destructor called ?
Hi googler.
I've been studying on msdn2 about these functions you've presented.
I have a couple questions and observations about your code.
1.) [OBSERVATION] Regarding while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
When I run it as is, PeekMessage never finds anything in the thread message queue. So there is never anything to translate and dispatch. If I remove the entire while loop, the program runs the same.
But I'm guessing the point of this is to show me that if I wanted to Post or Send a Message to this thread message queue, it would translate and dispatch it.
2) [QUESTION] What kind of Msg can be dispatched to the thread ? would that be messages to either kill the thread or parameters for the thread to work upon?
3.) [QUESTION] According to MSDN2 "The DispatchMessage function dispatches a message to a window procedure." Which procedure are you dispatching this message to in your code --- DispatchMessage(&msg); ?
4.) [QUESTION] Is handles[0] hardcoded because you are coding to a scenario that requires just 1 thread at a time ? If there were multiple threads in the queue and the 3rd signaled (that it was finished ) then result would return 3 , then maybe you would have to work upon handles[3]? Let me know.
4b. I noticed that when I set #define NUM_THREADS 3 I get some hard to explain behavior are you able to clarify that behavior ?
4c. Referring to the code block below : handles[0] = tmanager.TheHandle(); always returns Not Null -- I guess this is because tmanager defined outside of the while and closed much later on in the code.
Code:
HANDLE handles[NUM_THREADS];
handles[0] = tmanager.TheHandle();
if (handles[0] == NULL) {
WaitMessage();
continue;
}
How does this solution compare to the use of Mutex etc.
I was trying to experiment with Mutex as seen form this website
http://www.relisoft.com/win32/active.html
and
http://www.relisoft.com/win32/watcher.html
Stephen