3

I want to know how does class object (not instances, but exactly classes) store in memory?

class A {
public:
    int a;
    virtual void f();
    virtual ~A();
};

class B : public A {
public:
    int b;
    void f() final override;
};

I know, that usually (not strongly described by standard) in case of this inheritance (B derived from A) we have:

memory: ....AB...

where AB is a class object of B (if I understand it correctly). If we go deeper (tried with clang and gcc), we can see something like (again, not strongly described in standard):

A
    vtptr*
    int a
B
    vtptr*
    int b

Okay, now we see where do the a and b properties store. And we also see the pointer to virtual method table. But where does vtptr* (virtual method table) actually store? Why not near with the classes? Or it does?

Also, here is another question: I was able to change virtual method tables by changing the pointers (simple logic). Can I also change a pointer to it's methods safely?

P.S. In your questions you may answer for gcc and clang. P.P.S. If I am wrong somewhere please point it too in your answers.

VP.
  • 15,509
  • 17
  • 91
  • 161
  • 1
    Although you may find similar implementations this is implementation dependent. You will have to specifiy the compiler to get a sensible answer. – harper Mar 04 '15 at 08:19
  • 1
    The vtables aren't stored in the objects because it would be very inefficient, memory-wise. There's nothing in the standard the would prevent an implementation from doing so, however. I understand your curiosity, but you as long as you're writing sane code, you should rarely, if ever, have to worry about implementation details. Also, messing with the vtable or vtptrs (as well as doing anything that isn't strictly defined by the standard) is never considered to be safe. – glank Mar 04 '15 at 08:22
  • Maybe you'll understand a little more if you'll look at result of `g++ -fdump-class-hierarchy -c filename.cpp` – borisbn Mar 04 '15 at 08:28
  • In some places you use class to mean instance (e.g. *Why not near with the classes*). This is strange to me because you specifically delineate instance from class in the first sentence. – thang Mar 04 '15 at 08:46

3 Answers3

3

The C++ standard does not prescribe how the virtual function mechanism should be implemented. In practice all C++ implementations use a virtual function table per class, and a virtual function table pointer in each object of class with virtual functions (called a polymorphic class). Yet the details can differ, in particular for multiple inheritance and virtual inheritance.

You can read about the common choices in Stanley Lippman's classic book Inside The C++ Object Model.

It doesn't make much sense to ask “where” a virtual function table is stored. It's much like any static variable: its location depends on the implementation and is pretty much arbitrary. And regarding

Why not near with the classes?

… classes as such are not stored anywhere, they are not objects, so this doesn't make sense, sorry.

You can ask more meaningfully where is the vtable pointer stored in each object, for a given implementation?

And usually that's at the start of the object, but if you derive from a non-polymorphic class, and add a virtual function, then you might get the vtable pointer somewhere else. Or not. The latter possibility is much of the reason why a static_cast of Derived* to Base* (or vice versa) can do an address adjustment, i.e. is different from a simple reinterpret_cast.

Cheers and hth. - Alf
  • 142,714
  • 15
  • 209
  • 331
1

Read the wikipage on virtual method table.

Where is the vtable (itself) stored is implementation specific (compiler, linker, operating-system specific). But it is often stored (like literal strings are) in the code segment of your executable. So objects generally (i.e. without multiple inheritance) start with a _vptr pointer pointing to their vtable. With multiple or virtual inheritance you could have several vtable pointers.

As commented, you should not care about these details. If you really care, ask your compiler to dump internal representations or emitted assembly code. (e.g. compile with g++ -fdump-tree-all -fverbose-asm -S)

Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547
0

But where does vtptr* (virtual method table) actually [point]? Why not near with the classes? Or it does?

It could be anywhere... who cares? The way it works it's often implemented is a bit like this... imagine there's a hidden static member for class A:

VDT A::vdt = {
    { address of A::f code, 
      address of A::~A code },
    miscellaneous type-specific information needed for dynamic cast etc.
};

The exact layout's unknown, but there could well be an array of addresses of virtual member functions. As with any static information, the address is unrelated to the address of any given object instance... the pointers in the objects to the virtual dispatch table are there to allow this decoupling.

Also, here is another question: I was able to change virtual method tables by changing the pointers (simple logic). Can I also change a pointer to it's methods safely?

This is not safe, and even if it ostensibly works sometimes it may not be honoured consistently (e.g. in situations where the compiler's able to determine the specific override to call at compile time, it may bypass the runtime virtual dispatch table consultation completely).

Tony Delroy
  • 102,968
  • 15
  • 177
  • 252