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 hasthis
as an implicit, often first, parameter). For example yourgetA
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()
intoC$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 additionalvirtual void print(std::ostream&);
method, then yourclass A
would have the same layout asstruct 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 likep->print(std::cout);
would be translated almost likep->_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 virtual
destructor, 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
Warning: Returning Reference to Temporary
What Exactly Are C++ Definitions, Declarations and Assignments
How to Use Boost Preprocessor to Generate Accessors
Member Fields, Order of Construction
Why the Sizeof(Bool) Is Not Defined to Be One, by the Standard Itself
How to Avoid Including Class Implementation Files
C++ Add Months to Chrono::System_Clock::Time_Point
Inserting into a Vector at the Front
Calculate Rolling/Moving Average in C++
Capturing a Time in Milliseconds
Why Does 'Int ;' Compile Fine in C, But Not in C++
Cpu Dispatcher for Visual Studio for Avx and Sse
How Performing Multiple Matrix Multiplications in Cuda
Difference Between Initialization of Static Variables in C and C++