Connecting Tech Pros Worldwide Forums | Help | Site Map

Cast from void* to base class virtual function problem

Luke Dalessandro
Guest
 
Posts: n/a
#1: Sep 18 '05
Code: Thread -> U
-> T

public class Thread {
protected:
thread_t _tid;
virtual void foo() = 0;

public:
// Static entry function for the internal thread
static void* ThreadEntry(void* pThread) {
Thread* thread = static_cast<Thread*>(pThread);

// ***
// *** This is the error, calls the pure virtual version...?
// ***
thread->foo();
return 0;
}

// Starts the internal thread running
void Start() {
pthread_create(&_tid, NULL, Thread::ThreadEntry, this);
}
}

public class T : public Thread {
protected:
virtual void foo() {
cout << "I'm a T";
}
}

public class U : public Thread {
protected:
virtual void foo() {
cout << "I'm a U";
}
}

As you can see I'm just trying to re-use some pthread code for a
multithreaded server that spawns new threads for different reasons. I
can't figure out how to cast the void* to a base Thread* pointer and
call the pure virtual "foo" function and get the derived behavior...

Of course, the standard usage like

Thread* u = new U();
u->foo();

calls the derived foo like I expect.

I also tried a non-pure virtual foo and the Thread::foo is still getting
called after the cast.

I'm on OSX 10.4 development version. Not sure which gcc it is.

Thanks in advance,
Luke

Greg
Guest
 
Posts: n/a
#2: Sep 18 '05

re: Cast from void* to base class virtual function problem



Luke Dalessandro wrote:[color=blue]
> Code: Thread -> U
> -> T
>
> public class Thread {
> protected:
> thread_t _tid;
> virtual void foo() = 0;
>
> public:
> // Static entry function for the internal thread
> static void* ThreadEntry(void* pThread) {
> Thread* thread = static_cast<Thread*>(pThread);
>
> // ***
> // *** This is the error, calls the pure virtual version...?
> // ***
> thread->foo();
> return 0;
> }
>
> // Starts the internal thread running
> void Start() {
> pthread_create(&_tid, NULL, Thread::ThreadEntry, this);
> }
> }
>
> public class T : public Thread {
> protected:
> virtual void foo() {
> cout << "I'm a T";
> }
> }
>
> public class U : public Thread {
> protected:
> virtual void foo() {
> cout << "I'm a U";
> }
> }[/color]

[color=blue]
> As you can see I'm just trying to re-use some pthread code for a
> multithreaded server that spawns new threads for different reasons. I
> can't figure out how to cast the void* to a base Thread* pointer and
> call the pure virtual "foo" function and get the derived behavior...
>
> Of course, the standard usage like
>
> Thread* u = new U();
> u->foo();
>
> calls the derived foo like I expect.
>
> I also tried a non-pure virtual foo and the Thread::foo is still getting
> called after the cast.
>
> I'm on OSX 10.4 development version. Not sure which gcc it is.
>
> Thanks in advance,
> Luke[/color]

The code that allocates the Thread object for each pthread created is
missing from your post. In fact there is no obvious execution order to
the code that was posted.

Without knowing what pThread is actually pointing to, it's not possible
to fully diagnose the problem. It's also possible that there is no code
in the program to create new Thread objects, in which case the same
pThread pointer is being passed to every pthread.

Greg

Axter
Guest
 
Posts: n/a
#3: Sep 18 '05

re: Cast from void* to base class virtual function problem



Luke Dalessandro wrote:[color=blue]
> Code: Thread -> U
> -> T
>
> public class Thread {
> protected:
> thread_t _tid;
> virtual void foo() = 0;
>
> public:
> // Static entry function for the internal thread
> static void* ThreadEntry(void* pThread) {
> Thread* thread = static_cast<Thread*>(pThread);
>
> // ***
> // *** This is the error, calls the pure virtual version...?
> // ***
> thread->foo();
> return 0;
> }
>
> // Starts the internal thread running
> void Start() {
> pthread_create(&_tid, NULL, Thread::ThreadEntry, this);
> }
> }
>
> public class T : public Thread {
> protected:
> virtual void foo() {
> cout << "I'm a T";
> }
> }
>
> public class U : public Thread {
> protected:
> virtual void foo() {
> cout << "I'm a U";
> }
> }
>
> As you can see I'm just trying to re-use some pthread code for a
> multithreaded server that spawns new threads for different reasons. I
> can't figure out how to cast the void* to a base Thread* pointer and
> call the pure virtual "foo" function and get the derived behavior...
>
> Of course, the standard usage like
>
> Thread* u = new U();
> u->foo();
>
> calls the derived foo like I expect.
>
> I also tried a non-pure virtual foo and the Thread::foo is still getting
> called after the cast.
>
> I'm on OSX 10.4 development version. Not sure which gcc it is.
>
> Thanks in advance,
> Luke[/color]

In C++, you don't put key word public before a class declaration.

Luke Dalessandro
Guest
 
Posts: n/a
#4: Sep 18 '05

re: Cast from void* to base class virtual function problem




Greg wrote:[color=blue]
> Luke Dalessandro wrote:
>[color=green]
>>Code: Thread -> U
>> -> T
>>
>>public class Thread {
>> protected:
>> thread_t _tid;
>> virtual void foo() = 0;
>>
>> public:
>> // Static entry function for the internal thread
>> static void* ThreadEntry(void* pThread) {
>> Thread* thread = static_cast<Thread*>(pThread);
>>
>> // ***
>> // *** This is the error, calls the pure virtual version...?
>> // ***
>> thread->foo();
>> return 0;
>> }
>>
>> // Starts the internal thread running
>> void Start() {
>> pthread_create(&_tid, NULL, Thread::ThreadEntry, this);
>> }
>>}
>>
>>public class T : public Thread {
>> protected:
>> virtual void foo() {
>> cout << "I'm a T";
>> }
>>}
>>
>>public class U : public Thread {
>> protected:
>> virtual void foo() {
>> cout << "I'm a U";
>> }
>>}[/color]
>
>
>[color=green]
>>As you can see I'm just trying to re-use some pthread code for a
>>multithreaded server that spawns new threads for different reasons. I
>>can't figure out how to cast the void* to a base Thread* pointer and
>>call the pure virtual "foo" function and get the derived behavior...
>>
>>Of course, the standard usage like
>>
>> Thread* u = new U();
>> u->foo();
>>
>>calls the derived foo like I expect.
>>
>>I also tried a non-pure virtual foo and the Thread::foo is still getting
>>called after the cast.
>>
>>I'm on OSX 10.4 development version. Not sure which gcc it is.
>>
>>Thanks in advance,
>>Luke[/color]
>
>
> The code that allocates the Thread object for each pthread created is
> missing from your post. In fact there is no obvious execution order to
> the code that was posted.
>
> Without knowing what pThread is actually pointing to, it's not possible
> to fully diagnose the problem. It's also possible that there is no code
> in the program to create new Thread objects, in which case the same
> pThread pointer is being passed to every pthread.
>
> Greg
>[/color]

Greg,

Sorry about the lack, I was trying to remove everything that didn't seem
necessary. The code is basically:

int main (int argc, const * char argv[]) {

string toExit;
Thread* t;

while (toExit != "exit") {

cin >> toExit;

if (toExit = "U") {
t = new U();
}
else {
t = new V();
}

t->Start();

delete t;

}

}

Constructors are:

Thread::Thread() {}
U::U() {}
V::V() {}

Destructors are:

virtual ~Thread() {}
virtual ~U() {}
virtual ~V() {}

I realize that the main thread s pulling the rug out from under the
pthreads that are running inside the Thread objects... I'm actually
storing the pointers somewhere and joining and deleting threads elsewhere.

Luke
Luke Dalessandro
Guest
 
Posts: n/a
#5: Sep 18 '05

re: Cast from void* to base class virtual function problem




Axter wrote:[color=blue]
> Luke Dalessandro wrote:
>[color=green]
>>Code: Thread -> U
>> -> T
>>
>>public class Thread {
>> protected:
>> thread_t _tid;
>> virtual void foo() = 0;
>>
>> public:
>> // Static entry function for the internal thread
>> static void* ThreadEntry(void* pThread) {
>> Thread* thread = static_cast<Thread*>(pThread);
>>
>> // ***
>> // *** This is the error, calls the pure virtual version...?
>> // ***
>> thread->foo();
>> return 0;
>> }
>>
>> // Starts the internal thread running
>> void Start() {
>> pthread_create(&_tid, NULL, Thread::ThreadEntry, this);
>> }
>>}
>>
>>public class T : public Thread {
>> protected:
>> virtual void foo() {
>> cout << "I'm a T";
>> }
>>}
>>
>>public class U : public Thread {
>> protected:
>> virtual void foo() {
>> cout << "I'm a U";
>> }
>>}
>>
>>As you can see I'm just trying to re-use some pthread code for a
>>multithreaded server that spawns new threads for different reasons. I
>>can't figure out how to cast the void* to a base Thread* pointer and
>>call the pure virtual "foo" function and get the derived behavior...
>>
>>Of course, the standard usage like
>>
>> Thread* u = new U();
>> u->foo();
>>
>>calls the derived foo like I expect.
>>
>>I also tried a non-pure virtual foo and the Thread::foo is still getting
>>called after the cast.
>>
>>I'm on OSX 10.4 development version. Not sure which gcc it is.
>>
>>Thanks in advance,
>>Luke[/color]
>
>
> In C++, you don't put key word public before a class declaration.
>[/color]

Lol... you're right... I've been stuck in C# land for too long (language
at work). Thanks for pointing that out... I didn't cut and paste the
code, I just re-wrote it in simplified form, so there was no compiler
around to yell at men.

Luke
Luke Dalessandro
Guest
 
Posts: n/a
#6: Sep 18 '05

re: Cast from void* to base class virtual function problem




Luke Dalessandro wrote:[color=blue]
>
>
> Greg wrote:
>[color=green]
>> Luke Dalessandro wrote:
>>[color=darkred]
>>> Code: Thread -> U
>>> -> T
>>>
>>> public class Thread {
>>> protected:
>>> thread_t _tid;
>>> virtual void foo() = 0;
>>>
>>> public:
>>> // Static entry function for the internal thread
>>> static void* ThreadEntry(void* pThread) {
>>> Thread* thread = static_cast<Thread*>(pThread);
>>>
>>> // ***
>>> // *** This is the error, calls the pure virtual version...?
>>> // ***
>>> thread->foo();
>>> return 0;
>>> }
>>>
>>> // Starts the internal thread running
>>> void Start() {
>>> pthread_create(&_tid, NULL, Thread::ThreadEntry, this);
>>> }
>>> }
>>>
>>> public class T : public Thread {
>>> protected:
>>> virtual void foo() {
>>> cout << "I'm a T";
>>> }
>>> }
>>>
>>> public class U : public Thread {
>>> protected:
>>> virtual void foo() {
>>> cout << "I'm a U";
>>> }
>>> }[/color]
>>
>>
>>
>>[color=darkred]
>>> As you can see I'm just trying to re-use some pthread code for a
>>> multithreaded server that spawns new threads for different reasons. I
>>> can't figure out how to cast the void* to a base Thread* pointer and
>>> call the pure virtual "foo" function and get the derived behavior...
>>>
>>> Of course, the standard usage like
>>>
>>> Thread* u = new U();
>>> u->foo();
>>>
>>> calls the derived foo like I expect.
>>>
>>> I also tried a non-pure virtual foo and the Thread::foo is still getting
>>> called after the cast.
>>>
>>> I'm on OSX 10.4 development version. Not sure which gcc it is.
>>>
>>> Thanks in advance,
>>> Luke[/color]
>>
>>
>>
>> The code that allocates the Thread object for each pthread created is
>> missing from your post. In fact there is no obvious execution order to
>> the code that was posted.
>>
>> Without knowing what pThread is actually pointing to, it's not possible
>> to fully diagnose the problem. It's also possible that there is no code
>> in the program to create new Thread objects, in which case the same
>> pThread pointer is being passed to every pthread.
>>
>> Greg
>>[/color]
>
> Greg,
>
> Sorry about the lack, I was trying to remove everything that didn't seem
> necessary. The code is basically:
>
> int main (int argc, const * char argv[]) {
>
> string toExit;
> Thread* t;
>
> while (toExit != "exit") {
>
> cin >> toExit;
>
> if (toExit = "U") {
> t = new U();
> }
> else {
> t = new V();
> }
>
> t->Start();
>
> delete t;
>
> }
>
> }
>
> Constructors are:
>
> Thread::Thread() {}
> U::U() {}
> V::V() {}
>
> Destructors are:
>
> virtual ~Thread() {}
> virtual ~U() {}
> virtual ~V() {}
>
> I realize that the main thread s pulling the rug out from under the
> pthreads that are running inside the Thread objects... I'm actually
> storing the pointers somewhere and joining and deleting threads elsewhere.
>
> Luke[/color]

Sigh...

I think I solved my own problem. I really was deleting the Thread object
while it's internal thread was still running. This was causing the "pure
virtual function call" because "this" (passed as a void*) had actually
been deleted, so casting it to a Thread didn't cast it to a U or a V.

If I'm more careful about the delete call, ie joining first or
something, it works fine. Multithreading gets me again...

Sorry to bother everyone.

Luke
Closed Thread