Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

I'm trying to understand what kind of memory hit I'll incur by creating a large array of objects. I know that each object - when created - will be given space in the HEAP for member variables, and I think that all the code for every function that belongs to that type of object exists in the code segment in memory - permanently.

Is that right?

So if I create 100 objects in C++, I can estimate that I will need space for all the member variables that object owns multiplied by 100 (possible alignment issues here), and then I need space in the code segment for a single copy of the code for each member function for that type of object( not 100 copies of the code ).

Do virtual functions, polymorphism, inheritance factor into this somehow?

What about objects from dynamically linked libraries? I assume dlls get their own stack, heap, code and data segments.

Simple example (may not be syntactically correct):

// parent class
class Bar
{
public:
    Bar()  {};
    ~Bar() {};

    // pure virtual function
    virtual void doSomething() = 0;

protected:
    // a protected variable
    int mProtectedVar;
}

// our object class that we'll create multiple instances of
class Foo : public Bar
{
public:
    Foo()  {};
    ~Foo() {};

    // implement pure virtual function
    void doSomething()          { mPrivate = 0; }

    // a couple public functions
    int getPrivateVar()         { return mPrivate; }
    void setPrivateVar(int v)   { mPrivate = v; }

    // a couple public variables
    int mPublicVar;
    char mPublicVar2;

private:
    // a couple private variables
    int mPrivate;
    char mPrivateVar2;        
}

About how much memory should 100 dynamically allocated objects of type Foo take including room for the code and all variables?

like image 970
petrocket Avatar asked Mar 15 '09 22:03

petrocket


People also ask

Where are functions stored in memory in C?

The short answer: It will be stored in the text or code section of the binary only once irrespective of the number of instances of the class created.

How a class is stored in memory?

In Java, when we only declare a variable of a class type, only a reference is created (memory is not allocated for the object). To allocate memory to an object, we must use new(). So the object is always allocated memory on the heap (See this for more details).

How is a function stored in memory?

This is because in machine code, a function is referenced by its location in RAM, not its name. The compiler-output object file may have a func entry in its symbol table referring to this block of machine code, but the symbol table is read by software, not something the CPU hardware can decode and run directly.

Are functions stored in stack or heap?

Functions are objects. Therefore, the function's identifier is in the stack, and the function's value is stored in the heap. A function creates an activation object when it's called.


2 Answers

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

like image 189
John Zwinck Avatar answered Sep 26 '22 21:09

John Zwinck


Code exists in the text segment, and how much code is generated based on classes is reasonably complex. A boring class with no virtual inheritance ostensibly has some code for each member function (including those that are implicitly created when omitted, such as copy constructors) just once in the text segment. The size of any class instance is, as you've stated, generally the sum size of the member variables.

Then, it gets somewhat complex. A few of the issues are...

  • The compiler can, if it wants or is instructed, inline code. So even though it might be a simple function, if it's used in many places and chosen for inlining, a lot of code can be generated (spread all over the program code).
  • Virtual inheritance increases the size of polymorphic each member. The VTABLE (virtual table) hides along with each instance of a class using a virtual method, containing information for runtime dispatch. This table can grow quite large, if you have many virtual functions, or multiple (virtual) inheritance. Clarification: The VTABLE is per class, but pointers to the VTABLE are stored in each instance (depending on the ancestral type structure of the object).
  • Templates can cause code bloat. Every use of a templated class with a new set of template parameters can generate brand new code for each member. Modern compilers try and collapse this as much as possible, but it's hard.
  • Structure alignment/padding can cause simple class instances to be larger than you expect, as the compiler pads the structure for the target architecture.

When programming, use the sizeof operator to determine object size - never hard code. Use the rough metric of "Sum of member variable size + some VTABLE (if it exists)" when estimating how expensive large groups of instances will be, and don't worry overly about the size of the code. Optimise later, and if any of the non-obvious issues come back to mean something, I'll be rather surprised.

like image 30
Adam Wright Avatar answered Sep 22 '22 21:09

Adam Wright