Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Class members and member functions memory location

Here is a simple C++ class, named A:

class A
{
public:
    explicit A() : m_a(0) { }
    explicit A(int a) m_a(a) { }
    int getA() const { return m_a; }
    void setA(int a) { m_a = a; }

private:
    int m_a;
}

This is what I know so far:

  • When you declare an object of a class instance, memory gets allocated for that object. The allocated memory is equivalent to the memory of its members summed up. So in my case, it is:sizeof(A) = sizeof(int) = sizeof(m_a)
  • All member functions of class A are stored somewhere in memory and all instances of class A use the same member functions.

This is what I don't know:

Where are member functions stored and how are they actually stored? Let's say that an int for example is stored on 4 bytes; I can imagine the RAM memory layout with 4 contiguous cells each storing a part of that int. How can I imagine this layout for a function?(this could sound silly, but I imagine functions must have a place in memory because you can have a pointer point to them). Also how and where are function instructions stored? My first perception was that functions and function instructions are stored in the program executable(and its dynamic or static libraries) but if this is true what happens when you create a function pointer? AFAIK function pointers point to locations in RAM memory, can they point to locations in program binaries? If yes, how does this work?

Can anyone explain to me how this works and point out if what I know is right or wrong?

like image 943
Jacob Krieg Avatar asked Mar 01 '14 19:03

Jacob Krieg


People also ask

Where are member functions stored in memory?

Normal member functions are stored in the . text section of your program. They do not take up extra memory per each instance, because a member function takes in a pointer to the class instance, rather than creating a whole new function for each instance.

Where are class members stored?

All member functions of class A are stored somewhere in memory and all instances of class A use the same member functions.

How member functions are stored in memory C++?

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.

Where are class members stored C++?

Class members are part of a class instance. Where they live depends upon where the instance lives. If you declare an instance of a class as an automatic variable, then it is on the stack. If you allocate it with operator new, then it is on the heap.


1 Answers

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 ....

like image 68
Basile Starynkevitch Avatar answered Sep 21 '22 13:09

Basile Starynkevitch