开发者

why the result is not in my expectation?

#include <iostream>
using namespace std;
typedef void (*pFun)(void);
class A
{
private:    
    int a; 
    int b;
    virtual void outPrint()
    {
        cout << b << endl;
    }
 public:
    A()
    {
        a = 3;      
        b = 4;
    }
};

int main() 
{   
    A obj;
    cout << *((int*)(&obj)+1) << endl;
    pFun pFunc;     
    pFunc = (pFun)*((int*)*(int*)(&obj));   
    pFunc();
    system("pause");
    return 0; 
}

when i call pFunc(), the result i think should be 4,but actually it's a random number. and i debug the program, finding that pFunc points to the outPrint function. i don't know wh开发者_开发技巧y,plz help me


Seems that you assume that the address of the object obj can be interpreted as an address of a function of the type you defined.

It cannot.

I'm not entirely sure why would you have such an assumption to begin with. You're probably assuming things about the internal implementation of the dynamic dispatch. But do take a note: A::outPrint that you expect to be called, accepts 1 parameter (this, that is not explicitly defined), whereas your typedef assumes no parameters. So even if the address casting works fine and the address you get is that of the member function (which is a stretch to begin with), your call is incorrect.

If you change the typedef to:

typedef void (*pFun)(A*);

and the call to

pFunc(&obj);

That might work. Yet, the behavior per spec is undefined, to the best of my understanding.


Adding 1 to a int* only has defined behaviour in the case of traversing an int[].

Every other cases, there are no definition of what should happen. It is implementation defined since the final memory position of the members are not defined.

Try solving the problem in a way that does not exploit compiler details but the standard.

Also, in the case you get the function address following this way, calling it as a static method (without an object), only can provide you several headaches.


I'm not quite sure what exactly it is you're trying to do. It looks like you're trying to directly manipulate the pointer in order to get the address of a method, but that's a very bad idea for about 6 different reasons. It is possible to get a pointer to a class method, but it's not bound to the object so you need to be careful.

I'd suggest you have a fundamental misunderstanding of pointers and C++ classes, which must be corrected before you can manage any of this safely. Most people don't need function pointers, and almost nobody needs method pointers.


You are relying on various "undefined behavior", hence the result depends on what compiler and platform you are running on.

(int*)&obj+1 (better if you write ((int*)&obj)+1 to avoid misinterpretations) is not necessarily the b member. There may be padding between members, and &obj may be not the same as &(obj.a) being obj a polymorphic object (so may be it has a vtable pointer in top of it).

If this is the case, *(int*)&obj is the vtable address treated as an int. Converting it to an int* (supposing int and pointer having same sizes) it points to the first vtable entry (most likely the address of outPrint), hence the "random number".

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜