Where Are Member Functions Stored for an Object

Where are member functions stored for an object?

Member functions or pointers to them aren't stored in the object. (virtual functions are typically called through a pointer stored in a table to which an object has a single pointer to) This would be a huge waste of memory. They're typically stored in a code memory section, and are known to the compiler. The object (*this) is typically passed as an invisible parameter so the functions know on which object to operate when they are called.

So, in layman terms, you'd have

 0x10001000    void A::foo
.......... {code for A::foo}

and

 push a;
call A::foo (0x10001000)
pop a;

where a is the object you're calling foo on.

Where are the functions inside of structs stored in memory?

Member functions are common functions of all objects of the structure type. So they are stored separately from objects. The size of the structure in your example is in fact the size of its data member. If a structure has virtual functions then it implicitly includes a pointer to the table of virtual function pointers as a data member for each object of the structure type.

Class members and member functions memory location

First, you need to understand the role of the linker and what are executables (usually executed in virtual memory) and address spaces & processes. On Linux, read about ELF and the execve(2) syscall. Read also Levine's Linkers & Loaders book and Operating Systems: Three Easy Pieces, and the C++11 standard n3337, and this draft report and a good C++ programming book, with this reference website.

Member functions can be virtual or plain functions.

  • A plain (non virtual) member function is just like a C function (except that it has this as an implicit, often first, parameter). For example your getA method is implemented like the following C function (outside of the object, e.g. in the code segment of the binary executable) :

    int C$getA(A*thisptr) const { return thisptr->m_a; }

    then imagine that the compiler is translating p->getA() into C$getA(p)

  • A virtual member function is generally implemented thru a vtable (virtual method table). An object with some virtual member functions (including destructor) has generally as its first (implicit) member field a pointer to such a table (generated elsewhere by the compiler). Your class A don't have any virtual method, but imagine if it had an additional virtual void print(std::ostream&); method, then your class A would have the same layout as

    struct A$ {
    struct A$virtualmethodtable* _vptr;
    int m_a;
    };

    and the virtual table might be

    struct A$virtualmethodtable {
    void (*print$fun) (struct A$*, std::ostream*);
    };

    (so adding other virtual functions means simply adding slot inside that vtable);
    and then a call like p->print(std::cout); would be translated almost like
    p->_vptr.print$fun(p,&std::cout); ... In addition, the compiler would generate as constant tables various virtual method tables (one per class).

NB: things are more complex with multiple or virtual inheritance.

In both cases, member functions don't eat any additional space in the object. If it is non-virtual, it is just a plain function (in the code segment). If it is virtual, it shares a slot in the virtual method table.

NB. If you compile with a recent GCC (i.e. with g++) or with a Clang (so clang++) you could pass it e.g. the -fdump-tree-all flag: it will produce hundreds of dump files showing partly -in a dumped textual form- some internal representations of the compiler, which you could inspect with a pager (e.g. less) or a textual editor. You could also use MELT or look at the assembly code produced with g++ -S -fverbose-asm -O1 ....

Where are functions of an object stored in memory?

Your function is not virtual, it is thus statically called : the compiler inserts a jump to the code segment corresponding to your function. No additional memory is used per instance.

Were your function virtual, your instance would carry a vpointer, which would be dereferenced to find its class' vtable, which would then be indexed to find the function pointer to be called, and finally jump there. The additional cost is thus one vtable per class (probably the size of one function pointer, times the number of virtuals functions of your class), and one pointer per instance.

Note that this is a common implementation of virtual calls, but is in no way enforced by the standard, so it could actually not be implemented like that at all but your chances are quite good. The compiler can also often bypass the virtual call system altogether if it has knowledge of the static type of your instance at compile time.

Where is local variable of member function created if object is created via new?

Member functions are not that different from free functions, they only implicitly get a this pointer as first parameter. So your member function is more or less equivalent to (lets forget about the fact that nothing in your A is actually accesible, because it is all private)

int get_a(A* obj)
{
int d;
return obj->a;
}

I hope this already answers your question. Whether obj was allocated via new or not makes no difference for d being on the stack.

where are the common member variables stored when defining a class?

It's not stored anywhere. It only receives a place in memory when you actually create an object of type A.

int main()
{
A obj1; // obj1.a will be on the "stack"
A* pObj2 = new A; // pObj2->a will be on the "heap"
}

memory layout of C++ object

Non-virtual member functions are extremely like regular non-member functions, with the only difference between them being a pointer to the class instance passed as a very first argument upon invocation.

This is done automatically by compiler, so (in pseudo-code) your call b.fun() can be compiled into

B::Fun(&b);

Where B::Fun can be seen as a usual function. The address of this function does not have to stored in actual object (all objects of this class will use the same function), and thus size of the class does not include it.

In C++, where in memory are class functions put?

It's not necessarily true that "each object - when created - will be given space in the HEAP for member variables". Each object you create will take some nonzero space somewhere for its member variables, but where is up to how you allocate the object itself. If the object has automatic (stack) allocation, so too will its data members. If the object is allocated on the free store (heap), so too will be its data members. After all, what is the allocation of an object other than that of its data members?

If a stack-allocated object contains a pointer or other type which is then used to allocate on the heap, that allocation will occur on the heap regardless of where the object itself was created.

For objects with virtual functions, each will have a vtable pointer allocated as if it were an explicitly-declared data member within the class.

As for member functions, the code for those is likely no different from free-function code in terms of where it goes in the executable image. After all, a member function is basically a free function with an implicit "this" pointer as its first argument.

Inheritance doesn't change much of anything.

I'm not sure what you mean about DLLs getting their own stack. A DLL is not a program, and should have no need for a stack (or heap), as objects it allocates are always allocated in the context of a program which has its own stack and heap. That there would be code (text) and data segments in a DLL does make sense, though I am not expert in the implementation of such things on Windows (which I assume you're using given your terminology).

How does GCC store member functions in memory?

For the purpose of in-memory data representation, a C++ class can have either plain or static member functions, or virtual member functions (including some virtualdestructor, if any).

Plain or static member functions do not take any space in data memory, but of course their compiled code take some resource, e.g. as binary code in the text or code segment of your executable or your process. Of course, they can also require static data (or thread-local data), or local data (e.g. local variables) on the call stack.

My answer is Linux oriented. I don't know Windows, and don't know how GCC work on it.

Virtual member functions are very often implemented thru virtual method table (or vtable); a class having some virtual member functions usually have instances with a single (assuming single-inheritance) vtable-pointer pointing to that vtable (which is practically some data packed in the text segment).

Notice that vtables are not mandatory and are not required by C++11 standard. But I don't know any C++ implementation not using them.

When you are using multiple-inheritance things become more complex, objects might have several vtable pointers.

So if you have a class (either a root class, or using single-inheritance), the consumption for virtual member functions is one vtable pointer per instance (plus the small space needed by the single vtable itself). It won't change (for each instance) if you have only one virtual member function (or destructor) or a thousand of them (what would change is the vtable itself). Each class has its own single vtable (unless it has no virtual member function), and each instance has generally one (for single-inheritance case) vtable pointer.

The GCC compiler is free to organize the vtable as it wishes (and its order and layout is an implementation detail you should not care about); see also this. In practice (for single-inheritance) for most recent GCC versions, the vtable pointer is the first word of the object, and the vtable contain function pointers in the order of virtual method declaration, but you should not depend on such details.

The GCC compiler is free to organize the functions in the code segment as it wishes, and it would actually reorder them (e.g. for optimizations). Last time I looked, it ordered them in reverse order. But you certainly should not depend on that order! BTW GCC can inline functions (even when not marked inline) and clone functions when optimizing. You could also compile and link with link-time optimizations (e.g. make CXX='g++ -flto -Os'), and you could ask for profile-guided optimizations (for GCC: -fprofile-generate, -fprofile-use, -fauto-profile etc...)

You should not depend on how the compiler (and linker) is organizing function code or vtables. Leave the optimizations to the compiler (and such optimizations depend upon your target machine, your compiler flags, and the compiler version). You might also use function attributes to give hints to the GCC (or Clang/LLVM) compiler (e.g. __attribute__((cold)), __attribute__((noinline)) etc etc....)

If you really need to know how functions are placed (which IMHO is very wrong), study the generated assembly code (e.g. using g++ -O -fverbose-asm -S) and be aware that it could vary with compiler versions!

If you need on Linux and Posix systems at runtime to find out the address of a function from its name, consider using dlsym (for Linux, see dlsym(3), which also documents dladdr). Be aware of name mangling, which you can disable by declaring such functions as extern "C" (see C++ dlopen minihowto).

BTW, you might compile and link with -rdynamic (which is very useful for dlopen etc...). If you really need to know the address of functions, use nm(1) as nm -C your-executable.

You might also read the ABI specification and calling conventions for your target platform (and compiler), e.g. Linux x86-64 ABI spec.



Related Topics



Leave a reply



Submit