Reputation: 61
I am trying hard to understand the concept of memory addressing difference between a variable declared in main program and a variable inside the instantiated class object !
My question is when i declare two variables for example "int a, int b" inside main program, it takes 4+4 bytes with a particular two address some where in the memory. example "a is in the memory 0x248444 and b is in 0x248448".... in this case is fine....
When it comes to class instantiated object with two variable "int c, int d", the object takes a memory address with 8 bytes example "0x248544", what about the address of "int c and int d" ?
So address of int c and int d are inside that object address "0x248544" ? Does int c and int d has a particular address ?
How to understand / what is the difference between instantiated class object address and address of variable inside that object ?
Hope my question is clear....
After searching in internet, I found a book called "inside the C++ object model" but for basic understanding of memory difference about the variable declared in the instantiated class object and variable declared in main. someone please help me to make myself clear.
Thanks in Advance.
Upvotes: 0
Views: 2807
Reputation: 16266
You can consider class instance as an envelop for its member variables. Size of class instance is the sum of sizes of its member variables plus optional padding between them. Often (inheritance and polymorphism can mess with this) the address of the first member variable is the same as the address of class instance. You can take addresses of members and investigate them in debugger to see how it works. E.g.
class C
{
public:
int a = 1;
int b = 2;
};
C c;
int* p_a = &c.a;
int* p_b = &c.b;
Check memory occupied by c
, you'll see values 1
and 2
inside.
The order of member variables is preserved and can affect size of class instance because of padding.
An instance of an empty class must have an address and so its size is never 0.
Member functions is a different story. While they are also somewhere in the memory, they are shared by all instances and so are stored in a single place, separate from instances.
Upvotes: 1
Reputation: 25526
Ok, you have a class C like this:
class C
{
int c;
int d;
};
An instance of class C (C c
) will occupy some memory, it needs (provided int is 4 bytes large - this is not necessarily the case on all machines, though) 8 bytes.
If an instance is located at address 0x248544, it will occupy exactly the byte at this address + the next subsequent ones. In such a simple class as above with out any further conditions, c will occupy the first four of these eight bytes, d the next four ones.
So c.c
has exactly the same address as your object c
, and c.d
is located four bytes afterwards, so will have address 0x248548.
Be aware, though, that the first member does not necessarily have the same address as your object! Lets modify our class C:
class C
{
virtual ~C() { } // virtual destructor -> C gets virtual!
int c;
int d;
};
Now, sizeof(C) will be 16(!) (provided pointers require 8 bytes storage, as on modern 64-bit hardware). Why? The class gets an additional pointer to a vtable, which is normally the first (but invisible) member of class C.
So c
will still be at address 0x248544, but now the (invisible) pointer to vtable shares this address; c.c
comes afterwards, thus is located at address 0x2484c and c.d
then is located at 0x24850.
In this respect, C++ is different from C, where the first member of a struct always shares the address of the struct itself...
Both in C and C++, though, two subsequent members do not necessarily have to "touch" each other, there might be some bytes padded in between - keyword byte alignment.
Additionally, C++ allows to reorder the members of a class:
Whereas in C, if struct member a
is declared before b
, then a
must be placed in front of b
in memory, too, this is in C++ only required for members of the same accessibility!
class C
{
int a;
public:
int b;
private:
int c;
};
The compiler now is allowed leave the order as is, but it could as well place b
in front of or after the other two - only a
is not allowed to be placed after c
.
Long story, short conclusion: All this memory layout stuff is much more complicated than you probably expected it to be...
Side note to vtables: The vtable pointer is not required to be there (in respect to the C++ standard) - if any compiler vendor finds a better solution to implement polymorphism, they are free to do so - if they find... But vtables are the current state of the art, kind of de-facto standard.
Upvotes: 4