strange thread error

Started by
2 comments, last by begadanet 14 years, 4 months ago
Hello. I've met strange situation. Could you hear me? Following code compiles ok, but run error like below. i don't know why happen like this.

          debug      release
compile    ok          ok
run       error        ok



Debug Error!

R6025
- pure virtual function call


source is below.

#include <windows.h>
#include <process.h>

class MyThread
{
public:
	MyThread() {}
	virtual ~MyThread() {}

	virtual	void ThreadFunc() = 0;
	static unsigned int WINAPI ThreadCall( void* aParam )
	{
		MyThread* pThread = (MyThread*) aParam;
		pThread->ThreadFunc();

		return 1;
	}

	bool Start()
	{
		m_ThreadHandle = (HANDLE) _beginthreadex(0, 0, ThreadCall, this, 0, &m_ThreadID);
		return true;
	}

	HANDLE	m_ThreadHandle;
	unsigned int m_ThreadID;
};

class Thread1 : public MyThread
{
public:
	Thread1() {}
	virtual ~Thread1() {}

	virtual void ThreadFunc()
	{
		printf("1");
	}
};

int _tmain(int argc, _TCHAR* argv[])
{
	{
		Thread1 thread;
		thread.Start();
	}

	getchar();

	return 0;
}


Advertisement
One potential bug I can see is that it's possible for your main function to exit while the thread is still running.
You should probably add a call inside ~MyThread() to wait for the thread to finish.
I think Hodgman is correct here. What is likely happening is this:

1) Your "thread" instance is constructed
2) The Start() function is called, which in turn calls _beginthreadex to create a thread
3) Your "thread" instance loses scope and is destroyed (most likely an error in debug as the memory will be cleared out and so the VTABLE is zeroed, hence the pure virtual function call error)
4) The thread scheduler then begins your thread, which tries to call the virtual function, the entry for which is now 0 (i.e. a pure virtual function call).

The reason you're probably not seeing it in release is that the memory will not be getting zeroed by the runtime, but is still unallocated, so even though it appears to work, it's actually very dangerous.

The solution here is to ensure that the thread has completed before the "thread" instance is destroyed (which can be done in the destructor).

thank you very much,Hodgman, f8k8.

i solved that problem because of help both of you.

This topic is closed to new replies.

Advertisement