What Does an Object Look Like in Memory

What does an object look like in memory?

Static class members are treated almost exactly like global variables / functions. Because they are not tied to an instance, there is nothing to discuss regarding memory layout.

Class member variables are duplicated for each instance as you can imagine, as each instance can have its own unique values for every member variable.

Class member functions only exist once in a code segment in memory. At a low level, they are just like normal global functions but they receive a pointer to this. With Visual Studio on x86, it's via ecx register using thiscall calling convention.

When talking about virtual functions, polymorphism, then the memory layout gets more complicated, introducing a "vtable" which is basically a bunch of function pointers that define the topography of the class instance.

How would the memory look like for this object?

Each instance of a class or struct has a "personal memory space" for data, but methods are shared once for all objects.

First, you need 4 bytes on x32 or 8 bytes on x64 to store the reference to the memory address of the object (reference is a hidden pointer to forget to manage it).

Next, the object has two data members here:

  • One integer that takes 4 bytes.
  • One string that here takes 5 chars : 5x2 bytes = 10 bytes.

So for data the object takes 18 bytes on x32 or 22 bytes on x64 system.

Since string object contains an integer for the length, the size is a little more than that : 22 on x32 and 26 on x64.

Since string is a reference, we need to add again 4 or 8 bytes => 26 or 34 bytes.

Since string has some other static and instance fields in the class declaration like the first char, it takes a little more than this.

Is string actually an array of chars or does it just have an indexer?

In addition to that, the memory in the code segment has the instructions of the code of methods. This code is common for all instances.

In addition to that, there are class tables and virtual tables to describe types, methods signatures and polymorphism rules.

If the object is instantiated in a method it uses the heap memory.

If the object is instantiated in the declaration as a class member, I don't know how works .NET but it may be allocated in the data segment of the processus.

And memory is like a train where wagoons are the bytes.

Here is a pseudo-diagram of the memory.

It is not the very true reality but it may help to understand:

Sample Image

Does accessing a variable in C# class reads the entire class from memory?

C# Heap(ing) Vs Stack(ing) In .NET

A byte is the elementary unit of the memory that stores one value at a time between 0 and 255 (unsigned) or -128 and +127 (signed).

Learn the basics about C# data types' variables

Shifting Behavior for Signed Integers

A Tutorial on Data Representation


Seeing this sketch today (2021.01.28) I realize it may be mlisleading, and it is why I wrote "It is not the very true reality but it may help to understand", because in reality the code of the implementation of methods are loaded from the binary files EXE and DLLs when the process is starded and is stored is the CODE SEGMENT, as all data, static (literals) and dynamic (instances) are in the DATA SEGMENT (if things had not changed since x32 and protected mode). Methods' non-virtual tables as well as methods' virtual tables are not stored in the data segment for each instance of objects. I don't remember details but these tables is for code. Also Data of each instance of an object is a projection from its definition as well as its ancestors, in one place, one full instance.

Memory segmentation

x86 memory segmentation

Structure of a C++ Object in Memory Vs a Struct

The C++ standard guarantees that memory layouts of a C struct and a C++ class (or struct -- same thing) will be identical, provided that the C++ class/struct fits the criteria of being POD ("Plain Old Data"). So what does POD mean?

A class or struct is POD if:

  • All data members are public and themselves POD or fundamental types (but not reference or pointer-to-member types), or arrays of such
  • It has no user-defined constructors, assignment operators or destructors
  • It has no virtual functions
  • It has no base classes

About the only "C++-isms" allowed are non-virtual member functions, static members and member functions.

Since your class has both a constructor and a destructor, it is formally speaking not of POD type, so the guarantee does not hold. (Although, as others have mentioned, in practice the two layouts are likely to be identical on any compiler that you try, so long as there are no virtual functions).

See section [26.7] of the C++ FAQ Lite for more details.

How are objects stored in memory in C++?

Almost. You cast to an Object*, and neglected to take an address. Let's re-ask as the following:

((int*)&myObject)[0] == i1

You have to be really careful with assumptions like this. As you've defined the structure, this should be true in any compiler you're likely to come across. But all sorts of other properties of the object (which you may have omitted from your example) will, as others said, make it non-POD and could (possibly in a compiler-dependent way) make the above statement not true.

Note that I wouldn't be so quick to tell you it would work if you had asked about i3 -- in that case, even for plain POD, alignment or endianness could easily screw you up.

In any case, you should be avoiding this kind of thing, if possible. Even if it works fine now, if you (or anybody else who doesn't understand that you're doing this trick) ever changes the structure order or adds new fields, this trick will fail in all the places you've used it, which may be hard to find.

Answer to your edit: If that's your entire class definition, and you're using one of the mainstream compilers with default options, and running on an x86 processor, then yes, you've probably guessed the right memory layout. But choice of compiler, compiler options, and different CPU architecture could easily invalidate your assumptions.

How are objects stored in memory?

I'll start with the easiest-to-answer question:

Would it make a difference if the members of my Person class were fields rather than properties?

No. The properties in your code are just syntactic sugar. When the code is compiled, these properties with { get; set; } will be turned into fields, with a getter and a setter.

are there any major / obvious flaws in my understanding?

Yes. I will mention them when I answer the below questions.

Secondly, for value type members of a class (I.E Age), are they stored within the object itself (so within the same memory address as the object), or do they get allocated their own address, and the object then points to it? (Such as my diagram shows)

Your first statement is correct. Value types are stored within the object. There isn't a pointer in a Person object pointing to an int. In other words, your diagram is wrong.

but for reference type members, does the object hold a pointer to the pointer? (I.E The name pointer referencing the char collection in my diagram)

In this case, char[] is a reference type as you have noticed. But it's actually holding a bunch of chars, which are value types. So no, the characters are stored within the char array, just like the way Age is stored in Person. On the other hand, if this were a string[], there would be a pointer pointing to the array which would contain pointers pointing to string objects. This also means that your diagram is wrong.

What does std::vector look like in memory?

It roughly looks like this (excuse my MS Paint masterpiece):

vector memory layout

The std::vector instance you have on the stack is a small object containing a pointer to a heap-allocated buffer, plus some extra variables to keep track of the size and and capacity of the vector.


So it seems as though when I push_back() to the numbers vector, its older elements change their location.

The heap-allocated buffer has a fixed capacity. When you reach the end of the buffer, a new buffer will be allocated somewhere else on the heap and all the previous elements will be moved into the new one. Their addresses will therefore change.


Does it maybe store them together, but moves them all together, when more space is needed?

Roughly, yes. Iterator and address stability of elements is guaranteed with std::vector only if no reallocation takes place.


I am aware, that std::vector is a contiguous container only since C++17

The memory layout of std::vector hasn't changed since its first appearance in the Standard. ContiguousContainer is just a "concept" that was added to differentiate contiguous containers from others at compile-time.

understanding exactly how an object is mapped in memory

This is purely implementation dependent(compilers) and most of the implementations tend to go with inserting vptr as the first element. Since it is the first element and beginning of the object address, indirection for the virtual function call invocation will be easier as there is no further offset calculation to identify the vptr. Similar questions be asked in stackoverflow before and found the below one is useful.
Why is vptr stored as the first entry in the memory of a class with virtual functions?



Related Topics



Leave a reply



Submit