内存管理

用一到题先小试牛刀,来理解一下内存分布

内存分段

  1. 栈又叫堆栈,非静态局部变量/函数参数/返回值等等,栈是向下增长的。
  2. 内存映射段是高效的I/O映射方式,用于装载一个共享的动态内存库。用户可使用系统接口创建共享共享内存,做进程间通信。
  3. 堆用于程序运行时动态内存分配,堆是可以上增长的。
  4. 数据段–存储全局数据和静态数据。
  5. 代码段–可执行的代码/只读常量。

C中的内存管理

malloc、calloc、realloc

void Test () 
{    
    int* p1 = (int*) malloc (sizeof (int)*4);    
    free(p1 );    // calloc/realloc/malloc 的区别是什么?      
    int* p2 = (int*) calloc(4, sizeof (int));    
    int* p3 = (int*) realloc(p2 , sizeof( int)*6);    
    // 这里需要free(p2)吗?    
    free(p1);    
}

其他知识点:
https://blog.csdn.net/sifanchao/article/details/80247647

什么是内存泄漏

内存泄漏也称作”存储渗漏”,用动态存储分配函数动态开辟的空间,在使用完毕后未释放,结果导致一直占据该内存单元。直到程序结束。(其实说白了就是该内存空间使用完毕之后未回收)即所谓内存泄漏。

内存泄漏形象的比喻是”操作系统可提供给所有进程的存储空间正在被某个进程榨干”,最终结果是程序运行时间越长,占用存储空间越来越多,最终用尽全部存储空间,整个系统崩溃。所以”内存泄漏”是从操作系统的角度来看的。这里的存储空间并不是指物理内存,而是指虚拟内存大小,这个虚拟内存大小取决于磁盘交换区设定的大小。由程序申请的一块内存,如果没有任何一个指针指向它,那么这块内存就泄漏了。

如何进行内存泄露检测?
_CrtDumpMemoryLeaks()

C++内存管理方式

C语言内存管理方式在C++中可以继续使用,同时C++又提出了自己的内存管理方式:
C++中通过new和delete运算符进行动态内存管理
new/delete动态管理对象 new[]/delete[]动态管理对象数组

void Test()
{
    int *p1 = new int;//单个整型的空间
    int *p2 = new int(3);//初始化
    int *p3 = new int[3];//一段连续的空间

    int *p4 = (int *)malloc(sizeof(int));
    if (NULL == p4)
        return;

    delete p1;
    delete p2;
    delete[] p3;
    free(p4);
}

new和delete、new[]和delete[]一定匹配使用,一定匹配使用,一定匹配使用!!!
否则,内置类型没有影响,自定义类型会出现内存泄露甚至崩溃的问题

C库malloc/free等来动态管理内存,为什么C++还要定义new/delete运算符来动态管理内存呢?

class Test
{
public:
    Test()
        :_data(0)
    {
        cout << "Test():" << this << endl;
    }
    ~Test()
    {
        cout << "~Test():" << this << endl;
    }
private:
    int _data;
};
int main()
{
    Test *p1 = new Test;//单个整型的空间
    Test *p2 = new Test[3];//一段连续的空间

    Test *p3 = (Test *)malloc(sizeof(Test));
    if (NULL == p3)
        return 0;

    delete p1;
    delete[] p2;
    free(p3);
    system("pause");
    return 0;
}


C++对象 的 new/delete需要分别调构造函数(初始化)和析构函数(清理)!!!

malloc/free和new/delete的区别和联系

  1. 它们都是动态管理内存的入口
  2. malloc/free是C/C++标准库的函数,new/delete是C++操作符
  3. malloc/free只是动态分配内存空间/释放空间。而new/delete除了分配空间还会调用构造函数和析构函数进行初始化与清理(清理成员)
  4. malloc/free需要手动计算类型大小且返回值会void*,new/delete可自己计算类型的大小,返回对应类型 的指针
  5. malloc失败返回0,new失败了会抛异常

new操作符&操作符new

  • new操作符 :new/delete 表达式是C++用来动态管理内存的关键字
  • 操作符new :操作符new是一个函数:
void * operator new (size_t size);
void operator delete (size_t size) 
void * operator new void 
operator delete[] (size_t size)

总结

  • operator new/operator delete、 operator new[]/operator delete[] 和 malloc/free用法一样
  • 他们只负责分配空间/释放空间,不会调用对象构造函数/析构函数来初始化/清理对象> - 实际operator new 和operator delete只是malloc和free的一层封装
  • new做了两件事
    1. 调用operator new分配空间。
    2. 调用构造函数初始化对象。
  • delete也做了两件事
    1. 调用析构函数清理对象
    2. 调用operator delete释放空间
  • new[N]
    1. 调用operator new分配空间。
    2. 调用N次构造函数分别初始化每个对象。
  • delete[]
    1. 调用N次析构函数清理对象。(思考这里怎么N是怎么来的?) 其实是编译器在new出的数组对象头指 针位置向前4个字节中记录了对象个数(4个字节对应一个int值),结合内存变化观察下这种情况。
    2. 调用operator delete释放空间

内存池

频繁的使用new或new[]或者malloc在堆上开辟空间,除了可能出现内存泄漏,还可能出现内存碎片,造成资源的浪费。
因此,我们使用内存池的思想处理编程时需要频繁开辟内存的想法。

内存池
则是在真正使用内存之前,先申请分配一定数量的、大小相等(一般情况下)的内存块留作备用。当有新的内存需求时,就从内存池中分出一部分内存块,若内存块不够再继续申请新的内存。这样做的一个显著优点是,使得内存分配效率得到提升。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值