1、类的对象存储空间?

  • 非静态成员的数据类型大小之和。
  • 编译器加入的额外成员变量(如指向虚函数表的指针)
  • 为了边缘对齐优化加入了padding

2、简要说明C++的内存分区

C++中的内存分区,分别是堆、栈、自由存储区、全局/静态存储区、常量存储区和代码区。如下图

c++内存管理_内存管理

栈:在执行函数时,函数内部局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内容容量有限。

堆:就是那些使用new或者malloc创建出来的存储区域,释放的时候需要程序员手动释放,delete或者free()。如果程序员没有释放,那么程序结束的时候,操作系统自动的回收资源。

全局/静态存储区:全局变量和静态变量被分配到同一块内存中,在以前的C语言中,全局变量和静态变量有分为初始化的和未初始化,在C++里面没有这个区分了,它们共同占用同一块内存区,在该区定义的变量若没有初始化,则会被自动初始化,例如int型变量自动初始化为零。

常量存储区:这是一块比较特殊的存储区,这里面存储的是常量,不允许修改。

代码区:存储函数体的二进制代码。

3、什么是内存池,如何实现

内存池(Memory Pool)是一种内存分配方式。 C++中我们通常习惯直接使用new、malloc等申请内存,这样做的缺点在于:由于所申请内存大小不确定,当频繁使用时会造成大量的内存碎片并进而降低性能。内存池则是真正使用内存之前,先申请分配一定数量的、大小相等(一般情况下)的内存块留作备用。当有新的内存需求时候,就从内存池中分出一部分内存块,若内存块不够再继续申请新的内存。这样做的一个显著优点是尽量避免了内存碎片,使得内存分配效率得到提升。

4、C++中类的数据成员和成员函数内存分布情况?

C++类是由结构体发展而来的。

举例:

#include <iostream>
using namespace std;

class Person
{
public:
    Person()
    {
        this->age = 23;
    }
    void printAge()
    {
        cout << this->age <<endl;
    }
    ~Person(){}
public:
    int age;
};

int main()
{
    Person p;
    cout << "对象地址:"<< &p <<endl;
    cout << "age地址:"<< &(p.age) <<endl;
    cout << "对象大小:"<< sizeof(p) <<endl;
    cout << "age大小:"<< sizeof(p.age) <<endl;
    return 0;
}
//输出结果
//对象地址:0x7fffec0f15a8
//age地址:0x7fffec0f15a8
//对象大小:4
//age大小:4

从代码运行结果来看,对象的大小和对象中的数据成员的大小一致,也就是说,成员函数不占用对象的内存。这是因为所有的函数都是存放在代码区,不管是全局函数,还是成员函数。

我们再来补充一下静态成员函数的存放问题:静态成员函数与一般成员函数的唯一区别就是没有this指针,因此不能访问非静态数据成员。

就像我前面提到的,所有函数都存放在代码区,静态函数也不例外。所有有人一看到 static 这个单词就主观的认为是存放在全局数据区,那是不对的。