CuriousMind
CuriousMind

Reputation: 15798

Function pointer memory usage

How much memory would it take to declare a function pointer. How about a function pointer pointing to a member function of a class?

[EDIT:] I guess my question wasn't clear. I am aware a function pointer to a member function takes up more memory space, I am wondering why...

Upvotes: 0

Views: 784

Answers (2)

David Schwartz
David Schwartz

Reputation: 182769

It's up to the implementation, but typically a pointer to a member function takes up the same amount of space a regular pointer takes up, plus the amount of space the offset to the this pointer takes, which is typically the same size as a pointer. So you would expect a pointer to a member function to be twice the size of a regular pointer.

Consider:

#include <iostream>
using namespace std;

class Base
{
    public:
    int q;
    Base() { ; }
    void BaseFunc () { cout << this << endl; }
};

class Derived : public Base
{
    public:
    int r;
    Derived() { ; }
    virtual void DerivedFunc () { cout << this << endl; }
};

int main ()
{
    Derived f;
    f.BaseFunc();
    f.DerivedFunc();
    void (*p1)();
    void (Derived::*p2)();

    cout << sizeof(p1) << " "  << sizeof(p2) << endl;
}

Example output:

0x7fffe4c3e328
0x7fffe4c3e320
8 16

So a pointer to a member function has to store two pieces of information -- which function to call and how to adjust the this pointer to point to the right section of the member data.

And for those who think the adjuster can be computed from the types, try this main:

int main ()
{
    Derived f;

    void (Derived::*p1)();
    p1 = &Derived::BaseFunc;
    (f.*p1)();
    p1 = &Derived::DerivedFunc;
    (f.*p1)();
}

The two invocations of (f.*p1)(); require different adjusters even though the types are the same. And, of course, invoking BaseFunc through a Base::(*)() pointer would require a different adjuster from invoking the same function through a Derived::(*)() pointer.

Upvotes: 1

Sergey Kalinichenko
Sergey Kalinichenko

Reputation: 726599

The answer is platform-dependent. You could find the answer for your specific platform by using sizeof.

Size of pointer to member function may not necessarily be the same as that of a regular function pointer, so you should write a test to output them both:

#include <iostream>
using namespace std;
void foo() {}
struct C {
    void bar();
};
int main() {
    cout << sizeof(&foo) << endl;
    cout << sizeof(&C::bar) << endl;
    return 0;
}

Demo.

Upvotes: 4

Related Questions