In this article, we will see the memory layout of different C Object. And how different storage & access specifiers affect this memory footprint. I am not going to discuss compiler augmented code, name mangling & working of any C mechanism related to memory as it is compiler & architecture-dependent. To keep this further simple, I have considered the standard stack growth direction i.e. downwards. And with the same, data members are represented inverted in memory(thanks to Thomas Vermeilh for pointing that out), that too I have ignored for simplicity. Although if you want to play around with the same, you can refer to this link. So, in nutshell, it’s just all about “How different objects are laid out in memory?” Contents [hide] Memory Layout of Simple & Non-Polymorphic Object in Cclass X { int x; float xx; public: X() {} ~X() {} void printInt() {} void printFloat() {} }; class X {
int x;
float xx;
public:
X() {}
~X() {}
void printInt() {}
void printFloat() {}
}; class X {
int x;
float xx;
public:
X() {}
~X() {}
void printInt() {}
void printFloat() {}
};
| | |------------------------| <------ X class object memory layout | int X::x | |------------------------| stack segment | float X::xx | | |------------------------| | | | \|/ | | | | ------|------------------------|---------------- | X::X() | |------------------------| | | X::~X() | | |------------------------| \|/ | X::printInt() | text segment |------------------------| | X::printFloat() | |------------------------| | | | |
|------------------------| <------ X class object memory layout
| int X::x |
|------------------------| stack segment
| float X::xx | |
|------------------------| |
| | \|/
| |
| |
------|------------------------|----------------
| X::X() |
|------------------------| |
| X::~X() | |
|------------------------| \|/
| X::printInt() | text segment
|------------------------|
| X::printFloat() |
|------------------------|
| | | | |------------------------| <------ X class object memory layout | int X::x | |------------------------| stack segment | float X::xx | | |------------------------| | | | \|/ | | | | ------|------------------------|---------------- | X::X() | |------------------------| | | X::~X() | | |------------------------| \|/ | X::printInt() | text segment |------------------------| | X::printFloat() | |------------------------| | |
Layout of an Object With Virtual Function & Static Data Memberclass X { int x; float xx; static int count; public: X() {} virtual ~X() {} virtual void printAll() {} void printInt() {} void printFloat() {} static void printCount() {} }; class X {
int x;
float xx;
static int count;
public:
X() {}
virtual ~X() {}
virtual void printAll() {}
void printInt() {}
void printFloat() {}
static void printCount() {}
}; class X {
int x;
float xx;
static int count;
public:
X() {}
virtual ~X() {}
virtual void printAll() {}
void printInt() {}
void printFloat() {}
static void printCount() {}
};
| | |------------------------| <------ X class object memory layout | int X::x | stack |------------------------| | | float X::xx | | |------------------------| |-------|--------------------------| | | X::_vptr |------| | type_info X | \|/ |------------------------| |--------------------------| | o | | address of X::~X() | | o | |--------------------------| | o | | address of X::printAll() | | | |--------------------------| | | ------|------------------------|------------ | static int X::count | /|\ |------------------------| | | o | data segment | o | | | | \|/ ------|------------------------|------------ | X::X() | |------------------------| | | X::~X() | | |------------------------| | | X::printAll() | \|/ |------------------------| text segment | X::printInt() | |------------------------| | X::printFloat() | |------------------------| | static X::printCount() | |------------------------| | | | |
|------------------------| <------ X class object memory layout
| int X::x |
stack |------------------------|
| | float X::xx |
| |------------------------| |-------|--------------------------|
| | X::_vptr |------| | type_info X |
\|/ |------------------------| |--------------------------|
| o | | address of X::~X() |
| o | |--------------------------|
| o | | address of X::printAll() |
| | |--------------------------|
| |
------|------------------------|------------
| static int X::count | /| |------------------------| |
| o | data segment
| o | |
| | \|/
------|------------------------|------------
| X::X() |
|------------------------| |
| X::~X() | |
|------------------------| |
| X::printAll() | \|/
|------------------------| text segment
| X::printInt() |
|------------------------|
| X::printFloat() |
|------------------------|
| static X::printCount() |
|------------------------|
| | | | |------------------------| <------ X class object memory layout | int X::x | stack |------------------------| | | float X::xx | | |------------------------| |-------|--------------------------| | | X::_vptr |------| | type_info X | \|/ |------------------------| |--------------------------| | o | | address of X::~X() | | o | |--------------------------| | o | | address of X::printAll() | | | |--------------------------| | | ------|------------------------|------------ | static int X::count | /| |------------------------| | | o | data segment | o | | | | \|/ ------|------------------------|------------ | X::X() | |------------------------| | | X::~X() | | |------------------------| | | X::printAll() | \|/ |------------------------| text segment | X::printInt() | |------------------------| | X::printFloat() | |------------------------| | static X::printCount() | |------------------------| | |
Layout of C Object With Inheritanceclass X { int x; string str; public: X() {} virtual ~X() {} virtual void printAll() {} }; class Y : public X { int y; public: Y() {} ~Y() {} void printAll() {} }; class X {
int x;
string str;
public:
X() {}
virtual ~X() {}
virtual void printAll() {}
};
class Y : public X {
int y;
public:
Y() {}
~Y() {}
void printAll() {}
}; class X {
int x;
string str;
public:
X() {}
virtual ~X() {}
virtual void printAll() {}
};
class Y : public X {
int y;
public:
Y() {}
~Y() {}
void printAll() {}
};
| | |------------------------------| <------ Y class object memory layout | int X::x | stack |------------------------------| | | int string::len | | |string X::str ----------------| | | char* string::str | \|/ |------------------------------| |-------|--------------------------| | X::_vptr |------| | type_info Y | |------------------------------| |--------------------------| | int Y::y | | address of Y::~Y() | |------------------------------| |--------------------------| | o | | address of Y::printAll() | | o | |--------------------------| | o | ------|------------------------------|-------- | X::X() | |------------------------------| | | X::~X() | | |------------------------------| | | X::printAll() | \|/ |------------------------------| text segment | Y::Y() | |------------------------------| | Y::~Y() | |------------------------------| | Y::printAll() | |------------------------------| | string::string() | |------------------------------| | string::~string() | |------------------------------| | string::length() | |------------------------------| | o | | o | | o | | | | |
|------------------------------| <------ Y class object memory layout
| int X::x |
stack |------------------------------|
| | int string::len |
| |string X::str ----------------|
| | char* string::str |
\|/ |------------------------------| |-------|--------------------------|
| X::_vptr |------| | type_info Y |
|------------------------------| |--------------------------|
| int Y::y | | address of Y::~Y() |
|------------------------------| |--------------------------|
| o | | address of Y::printAll() |
| o | |--------------------------|
| o |
------|------------------------------|--------
| X::X() |
|------------------------------| |
| X::~X() | |
|------------------------------| |
| X::printAll() | \|/
|------------------------------| text segment
| Y::Y() |
|------------------------------|
| Y::~Y() |
|------------------------------|
| Y::printAll() |
|------------------------------|
| string::string() |
|------------------------------|
| string::~string() |
|------------------------------|
| string::length() |
|------------------------------|
| o |
| o |
| o |
| | | | |------------------------------| <------ Y class object memory layout | int X::x | stack |------------------------------| | | int string::len | | |string X::str ----------------| | | char* string::str | \|/ |------------------------------| |-------|--------------------------| | X::_vptr |------| | type_info Y | |------------------------------| |--------------------------| | int Y::y | | address of Y::~Y() | |------------------------------| |--------------------------| | o | | address of Y::printAll() | | o | |--------------------------| | o | ------|------------------------------|-------- | X::X() | |------------------------------| | | X::~X() | | |------------------------------| | | X::printAll() | \|/ |------------------------------| text segment | Y::Y() | |------------------------------| | Y::~Y() | |------------------------------| | Y::printAll() | |------------------------------| | string::string() | |------------------------------| | string::~string() | |------------------------------| | string::length() | |------------------------------| | o | | o | | o | | |
Memory Layout of an Object With Multiple Inheritances & Virtual Functionclass X { public: int x; virtual ~X() {} virtual void printX() {} }; class Y { public: int y; virtual ~Y() {} virtual void printY() {} }; class Z : public X, public Y { public: int z; ~Z() {} void printX() {} void printY() {} void printZ() {} }; class X {
public:
int x;
virtual ~X() {}
virtual void printX() {}
};
class Y {
public:
int y;
virtual ~Y() {}
virtual void printY() {}
};
class Z : public X, public Y {
public:
int z;
~Z() {}
void printX() {}
void printY() {}
void printZ() {}
}; class X {
public:
int x;
virtual ~X() {}
virtual void printX() {}
};
class Y {
public:
int y;
virtual ~Y() {}
virtual void printY() {}
};
class Z : public X, public Y {
public:
int z;
~Z() {}
void printX() {}
void printY() {}
void printZ() {}
};
| | |------------------------------| <------ Z class object memory layout stack | int X::x | | |------------------------------| |--------------------------| | | X:: _vptr |----------------->| type_info Z | | |------------------------------| |--------------------------| \|/ | int Y::y | | address of Z::~Z() | |------------------------------| |--------------------------| | Y:: _vptr |------| | address of Z::printX() | |------------------------------| | |--------------------------| | int Z::z | | |--------GUARD_AREA--------| |------------------------------| | |--------------------------| | o | |---------->| type_info Z | | o | |--------------------------| | o | | address of Z::~Z() | | | |--------------------------| ------|------------------------------|--------- | address of Z::printY() | | X::~X() | | |--------------------------| |------------------------------| | | X::printX() | | |------------------------------| | | Y::~Y() | \|/ |------------------------------| text segment | Y::printY() | |------------------------------| | Z::~Z() | |------------------------------| | Z::printX() | |------------------------------| | Z::printY() | |------------------------------| | Z::printZ() | |------------------------------| | o | | o | | | | |
|------------------------------| <------ Z class object memory layout
stack | int X::x |
| |------------------------------| |--------------------------|
| | X:: _vptr |----------------->| type_info Z |
| |------------------------------| |--------------------------|
\|/ | int Y::y | | address of Z::~Z() |
|------------------------------| |--------------------------|
| Y:: _vptr |------| | address of Z::printX() |
|------------------------------| | |--------------------------|
| int Z::z | | |--------GUARD_AREA--------|
|------------------------------| | |--------------------------|
| o | |---------->| type_info Z |
| o | |--------------------------|
| o | | address of Z::~Z() |
| | |--------------------------|
------|------------------------------|--------- | address of Z::printY() |
| X::~X() | | |--------------------------|
|------------------------------| |
| X::printX() | |
|------------------------------| |
| Y::~Y() | \|/
|------------------------------| text segment
| Y::printY() |
|------------------------------|
| Z::~Z() |
|------------------------------|
| Z::printX() |
|------------------------------|
| Z::printY() |
|------------------------------|
| Z::printZ() |
|------------------------------|
| o |
| o |
| | | | |------------------------------| <------ Z class object memory layout stack | int X::x | | |------------------------------| |--------------------------| | | X:: _vptr |----------------->| type_info Z | | |------------------------------| |--------------------------| \|/ | int Y::y | | address of Z::~Z() | |------------------------------| |--------------------------| | Y:: _vptr |------| | address of Z::printX() | |------------------------------| | |--------------------------| | int Z::z | | |--------GUARD_AREA--------| |------------------------------| | |--------------------------| | o | |---------->| type_info Z | | o | |--------------------------| | o | | address of Z::~Z() | | | |--------------------------| ------|------------------------------|--------- | address of Z::printY() | | X::~X() | | |--------------------------| |------------------------------| | | X::printX() | | |------------------------------| | | Y::~Y() | \|/ |------------------------------| text segment | Y::printY() | |------------------------------| | Z::~Z() | |------------------------------| | Z::printX() | |------------------------------| | Z::printY() | |------------------------------| | Z::printZ() | |------------------------------| | o | | o | | |
Y *y_ptr = new Z; y_ptr->printY(); // OK y_ptr->printZ(); // Not OK, as virtual table of class Y doesn't have address of printZ() method Y *y_ptr = new Z;
y_ptr->printY(); // OK
y_ptr->printZ(); // Not OK, as virtual table of class Y doesn't have address of printZ() method Y *y_ptr = new Z;
y_ptr->printY(); // OK
y_ptr->printZ(); // Not OK, as virtual table of class Y doesn't have address of printZ() method
( *y_ptr->_vtbl[ 2 ] )( y_ptr ) ( *y_ptr->_vtbl[ 2 ] )( y_ptr ) ( *y_ptr->_vtbl[ 2 ] )( y_ptr )
Layout of Object Having Virtual Inheritanceclass X { int x; }; class Y : public virtual X { int y; }; class Z : public virtual X { int z; }; class A : public Y, public Z { int a; }; class X { int x; };
class Y : public virtual X { int y; };
class Z : public virtual X { int z; };
class A : public Y, public Z { int a; }; class X { int x; };
class Y : public virtual X { int y; };
class Z : public virtual X { int z; };
class A : public Y, public Z { int a; };
| | Y class ------> |----------------| <------ A class object memory layout sub-object | Y::y | |----------------| |------------------| | Y::_vptr_Y |------| | offset of X | // offset(20) starts from Y Z class ------> |----------------| |----> |------------------| sub-object | Z::z | | ..... | |----------------| |------------------| | Z::_vptr_Z |------| |----------------| | A sub-object --> | A::a | | |------------------| |----------------| | | offset of X | // offset(12) starts from Z X class -------> | X::x | |----> |------------------| shared |----------------| | ..... | sub-object | | |------------------| | |
Y class ------> |----------------| <------ A class object memory layout
sub-object | Y::y |
|----------------| |------------------|
| Y::_vptr_Y |------| | offset of X | // offset(20) starts from Y
Z class ------> |----------------| |----> |------------------|
sub-object | Z::z | | ..... |
|----------------| |------------------|
| Z::_vptr_Z |------|
|----------------| |
A sub-object --> | A::a | | |------------------|
|----------------| | | offset of X | // offset(12) starts from Z
X class -------> | X::x | |----> |------------------|
shared |----------------| | ..... |
sub-object | | |------------------| | | Y class ------> |----------------| <------ A class object memory layout sub-object | Y::y | |----------------| |------------------| | Y::_vptr_Y |------| | offset of X | // offset(20) starts from Y Z class ------> |----------------| |----> |------------------| sub-object | Z::z | | ..... | |----------------| |------------------| | Z::_vptr_Z |------| |----------------| | A sub-object --> | A::a | | |------------------| |----------------| | | offset of X | // offset(12) starts from Z X class -------> | X::x | |----> |------------------| shared |----------------| | ..... | sub-object | | |------------------|
Do you like it??? Get such articles directly into the inbox…!?? |
|
來自: astrotycoon > 《待分類》