Thread: Derived cast problem *eye twitch*

  1. #1
    Rat with a C++ compiler Rodaxoleaux's Avatar
    Join Date
    Sep 2011
    Location
    ntdll.dll
    Posts
    203

    Derived cast problem *eye twitch*

    This is one of things that I should've learned years ago and never really focused much on it. However, now it's causing a problem for me while trying to make an event class with separate events all derived from 'Event'.

    Code:
    Event* newEv = new NewDerivedEvent;
                newEv = m_EventHolder->Poll();
                NewDerivedEvent* ve;
                ve = static_cast<NewDerivedEvent*>(newEv);
    Doing, this, ve still has the type (Event*), which means that the variables I'm trying to siphon from the Event (which is verified that it is of DerivedEvent* type), does not exist and therefore causes a segfault. How is this normally done to cast a base class down to it's derived class. m_EventHolder->Poll() returns type (Event*) even though the thrown event is of the derived type. Is that the way it should be, or not?
    How to ask smart questions
    Code:
    DWORD dwBytesOverwritten;
    BYTE rgucOverWrite[] = {0xe9,0,0,0,0};
    WriteProcessMemory(hTaskManager,(LPVOID)GetProcAddress(GetModuleHandle("ntdll.dll"),"NtQuerySystemInformation"),rgucOverWrite,5,&dwBytesOverwritten);

  2. #2
    [](){}(); manasij7479's Avatar
    Join Date
    Feb 2011
    Location
    *nullptr
    Posts
    2,657
    Quote Originally Posted by Rodaxoleaux View Post
    Doing, this, ve still has the type (Event*), which means that the variables I'm trying to siphon from the Event (which is verified that it is of DerivedEvent* type), does not exist and therefore causes a segfault. How is this normally done to cast a base class down to it's derived class. m_EventHolder->Poll() returns type (Event*) even though the thrown event is of the derived type. Is that the way it should be, or not?
    Using dynamic_cast is a good idea. (afaik)

  3. #3
    Registered User hk_mp5kpdw's Avatar
    Join Date
    Jan 2002
    Location
    Northern Virginia/Washington DC Metropolitan Area
    Posts
    3,817
    Code:
    Event* newEv = new NewDerivedEvent;
    newEv = m_EventHolder->Poll();
    That doesn't look right... you allocate space to newEv and then reassign it another value returned by that Poll function? Is that a memory leak?
    "Owners of dogs will have noticed that, if you provide them with food and water and shelter and affection, they will think you are god. Whereas owners of cats are compelled to realize that, if you provide them with food and water and shelter and affection, they draw the conclusion that they are gods."
    -Christopher Hitchens

  4. #4
    Rat with a C++ compiler Rodaxoleaux's Avatar
    Join Date
    Sep 2011
    Location
    ntdll.dll
    Posts
    203
    Quote Originally Posted by manasij7479 View Post
    Using dynamic_cast is a good idea. (afaik)
    I heard that static_cast was more efficient and that sometimes the compiler will optimize dynamic_cast to a static cast.

    Maybe it is a memory leak. I'm not sure but I don't know how to correct it. I've tried a lot of ways.
    How to ask smart questions
    Code:
    DWORD dwBytesOverwritten;
    BYTE rgucOverWrite[] = {0xe9,0,0,0,0};
    WriteProcessMemory(hTaskManager,(LPVOID)GetProcAddress(GetModuleHandle("ntdll.dll"),"NtQuerySystemInformation"),rgucOverWrite,5,&dwBytesOverwritten);

  5. #5
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by Rodaxoleaux
    Doing, this, ve still has the type (Event*), which means that the variables I'm trying to siphon from the Event (which is verified that it is of DerivedEvent* type), does not exist and therefore causes a segfault.
    It can help if you properly established the relationship between Event, DerivedEvent and NewDerivedEvent. I'm going to assume that DerivedEvent and NewDerivedEvent are derived from Event, but are otherwise not related, and that newEv points to a DerivedEvent object. In that case, this results in undefined behaviour:
    Code:
    ve = static_cast<NewDerivedEvent*>(newEv);
    On the other hand, if newEv points to a NewDerivedEvent, then your reasoning does not hold: ve has the type NewDerivedEvent*, and it points to a NewDerivedEvent object. The static_cast works.

    If you are not certain as to what is the actual type of the object pointed to, then manasij7479's suggestion of dynamic_cast is a correct approach. However, before you reach for dynamic_cast: why do you need to treat the object as a NewDerivedEvent object instead of an Event object? Can you not design the Event interface such that you can just operate using that here?

    By the way, this looks wrong:
    Code:
    Event* newEv = new NewDerivedEvent;
    newEv = m_EventHolder->Poll();
    You use new to create a NewDerivedEvent object, and set newEv to point to it, but immediately afterwards, you overwrite newEv such that you can no longer use delete to destroy the NewDerivedEvent object previously created.
    Last edited by laserlight; 02-22-2012 at 11:37 AM.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  6. #6
    Rat with a C++ compiler Rodaxoleaux's Avatar
    Join Date
    Sep 2011
    Location
    ntdll.dll
    Posts
    203
    Quote Originally Posted by laserlight View Post
    It can help if you properly established the relationship between Event, DerivedEvent and NewDerivedEvent. I'm going to assume that DerivedEvent and NewDerivedEvent are derived from Event, but are otherwise not related, and that newEv points to a DerivedEvent object. In that case, this results in undefined behaviour:
    Code:
    ve = static_cast<NewDerivedEvent*>(newEv);
    On the other hand, if newEv points to a NewDerivedEvent, then your reasoning does not hold: ve has the type NewDerivedEvent*, and it points to a NewDerivedEvent object. The static_cast works.

    If you are not certain as to what is the actual type of the object pointed to, then manasij7479's suggestion of dynamic_cast is a correct approach. However, before you reach for dynamic_cast: why do you need to treat the object as a NewDerivedEvent object instead of an Event object? Can you not design the Event interface such that you can just operate using that here?

    By the way, this looks wrong:
    Code:
    Event* newEv = new NewDerivedEvent;
    newEv = m_EventHolder->Poll();
    You use new to create a NewDerivedEvent object, and set newEv to point to it, but immediately afterwards, you overwrite newEv such that you can no longer use delete to destroy the NewDerivedEvent object previously created.
    There are only two types: Event (The base class), and NewDerivedEvent (the derived class of Event). The reason I cannot design the event class to have the members that NewDerivedEvent that is because the events derived have no relation whatsoever. One could be a new connection event (in this case) that contains the IP of the connection. One is also an event for waiting data from a connection, which is just a signal, and I just want to use the variables of the derived class since that seems a lot more efficient. Is there no way to do this? o.o
    How to ask smart questions
    Code:
    DWORD dwBytesOverwritten;
    BYTE rgucOverWrite[] = {0xe9,0,0,0,0};
    WriteProcessMemory(hTaskManager,(LPVOID)GetProcAddress(GetModuleHandle("ntdll.dll"),"NtQuerySystemInformation"),rgucOverWrite,5,&dwBytesOverwritten);

  7. #7
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by Rodaxoleaux
    There are only two types: Event (The base class), and NewDerivedEvent (the derived class of Event).
    In that case, there is no reason why the static_cast should fail. Changing to dynamic_cast won't help because the problem lies elsewhere.

    The problem is that your next statement makes it clear that static_cast will fail when you implement this for real because you don't know what is the actual type of the Event at compile time.

    Quote Originally Posted by Rodaxoleaux
    The reason I cannot design the event class to have the members that NewDerivedEvent that is because the events derived have no relation whatsoever. One could be a new connection event (in this case) that contains the IP of the connection. One is also an event for waiting data from a connection, which is just a signal, and I just want to use the variables of the derived class since that seems a lot more efficient. Is there no way to do this?
    If there is no Event interface, then inheritance is the wrong tool for the job (or maybe you're inheriting an implementation instead, but that's obviously not the case here). If it really turns of that each Event derived class does things rather differently, at the very least you could provide an Event interface that allows for you to apply the visitor pattern.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  8. #8
    Rat with a C++ compiler Rodaxoleaux's Avatar
    Join Date
    Sep 2011
    Location
    ntdll.dll
    Posts
    203
    Quote Originally Posted by laserlight View Post
    In that case, there is no reason why the static_cast should fail. Changing to dynamic_cast won't help because the problem lies elsewhere.

    The problem is that your next statement makes it clear that static_cast will fail when you implement this for real because you don't know what is the actual type of the Event at compile time.


    If there is no Event interface, then inheritance is the wrong tool for the job (or maybe you're inheriting an implementation instead, but that's obviously not the case here). If it really turns of that each Event derived class does things rather differently, at the very least you could provide an Event interface that allows for you to apply the visitor pattern.
    Indeed. I have rewritten the Event class to have a member (Data) that holds any strings that the derived events need so they just put the information in there. I didn't know there were limits like that, but either way. Problem Solved.
    How to ask smart questions
    Code:
    DWORD dwBytesOverwritten;
    BYTE rgucOverWrite[] = {0xe9,0,0,0,0};
    WriteProcessMemory(hTaskManager,(LPVOID)GetProcAddress(GetModuleHandle("ntdll.dll"),"NtQuerySystemInformation"),rgucOverWrite,5,&dwBytesOverwritten);

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Problem with sqrt and cast
    By Roger in forum C Programming
    Replies: 1
    Last Post: 12-23-2009, 01:53 PM
  2. Cast problem
    By Kempelen in forum C Programming
    Replies: 7
    Last Post: 06-16-2008, 06:36 AM
  3. Problem with cast
    By bumbleb33 in forum C Programming
    Replies: 3
    Last Post: 04-19-2008, 04:21 AM
  4. Maybe A Cast Problem?
    By relyt_123 in forum C++ Programming
    Replies: 26
    Last Post: 07-30-2006, 06:45 PM
  5. problem with data cast
    By davide_82 in forum Networking/Device Communication
    Replies: 2
    Last Post: 09-28-2005, 12:44 AM