内存管理

来源:互联网 发布:同城约爱用什么软件 编辑:程序博客网 时间:2024/06/08 03:30

内存分配方式

  • 从静态存储区域分配

    内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在。(全局变量,静态变量)

  • 在栈上创建

    在函数执行时,函数内部局部变量的存储单元都可以在栈上创建,函数执行结束自动释放。(效率高,但分配的内存空间有限)

  • 从堆上分配,亦称动态内存分配

    使用malloc/new等申请的空间,用free/delete等释放,用户自己管理。

这里写图片描述

C语言中动态内存管理

  • void *malloc( size_t size )
    int* pStr = (int*)malloc(10*sizeof(int));//申请    assert(pStr);//判空    free(Pstr);//释放


  • void *calloc(size_t num, size_t size)

该函数将申请的内存空间初始化为0
    char* pStr = (char*)calloc(10,sizeof(char));//申请    assert(pStr);    free(pStr);//释放


  • void *realloc( void *memblock, size_t size )

改变原有空间的大小,若空间不足,则重新开辟空间,将原有的数据拷贝过去,释放原来的空间
    int* P1 = (int*)malloc(10 * sizeof(int));//第一次申请    realloc(P1, 20 * sizeof(int));//重新申请    free(P1);//释放

堆上的内存需要用户自己来管理,动态malloc/calloc/realloc开辟的空间,必须free掉,不然会出现内存泄漏
栈上的空间具有函数作用域,在函数结束后系统会自动回收,不需用户管理

常见内存泄漏
    //内存申请了,没有释放    int* P1 = (int*)malloc(10 * sizeof(int));    assert(P1);    Dosomething();    //程序逻辑不清,以为释放了    int* P2 = (int*)malloc(10 * sizeof(int));    int* P3 = (int*)malloc(10 * sizeof(int));    assert(P2);    Dosomething();    P2= P3;    free(P2);    free(P3);//程序中断    //程序将堆破坏    char* P4 = (char*)malloc(5*sizeof(char));    assert(P4);    //char *strcpy( char *strDestination, const char *strSource );    strcpy(P4, "hello world!");    free(P4);//程序中断    //释放是传入的地址和申请的不同    int* P5= (int*)malloc(10 * sizeof(int));    assert(P5);    P5[0] = 1;    P5++;    free(P5);//程序中断    //释放之后,未将指针置为NULL,产生野指针    int* P6 = (int*)malloc(10 * sizeof(int));    assert(P6);    Dosomething();    free(P6);    //P6 = NULL;    //函数return语句写错了    //不能返回栈内存的指针或引用

C++中动态内存管理

C++中通过new和delete运算符进行内存管理

void test(){    int* p1 = new int;   //动态分配一个整型大小的空间    int* p2 = new int(2);    //动态分配1个整型大小的空间并初始化为2    int* p3 = new int[3];    //动态分配3个整型大小的空间并初始化为2    delete p1;    delete p2;    delete [] p3;}//new 和 delete 、 new [] 和delete []  一定要配套使用
C++的其他内存管理接口


  • void* operator new(size_t size)
  • void operator delete (size_t size)
  • void* operator new [] (size_t size)
  • void operator delete [] (size_t size)

operator new/operator delete/operator new []/operator delete[] 只是对malloc/free的一层封装,功能和malloc/free一样,只是进行内存的分配和释放,不会调用构造函数和析构函数
深度剖析new/delete

这里写图片描述

深度剖析new[]/delete[]

这里写图片描述

定位new表达式
  • 在已分配的空间上调用构造函数初始化一个对象
    这里写图片描述
class Array{public:    Array(size_t size = 10)        :_size(size)        ,_a(0)    {        cout << "Array(szie_t size)"<<endl;        if (_size > 0)        {            _a = new int[size];        }    }    ~Array()    {        cout << "Array()" << endl;        if (_a)        {            delete[] _a;            _a = 0;            _size = 0;        }    }private:    int* _a;    size_t _size;};void Funtest(){    //malloc/free+定位表达式new(),显示调用构造函数,模拟new/delete    Array* p1 = (Array*)malloc(sizeof(Array));    new(p1)Array(12);//定位new表达式    p1->~Array();    free(p1);    //malloc / free +多次调用定位表达式new(), 显示多次调用构造函数,模拟new []/ delete[]    Array* p2 = (Array*)malloc(10 * sizeof(Array));    for (int i = 0; i < 10; i++)    {        p2[i].~Array;    }    free(p2);}

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

  • 都是动态内存管理的入口
  • malloc/free是C/C++的标准库函数,new/delete是C++的运算符
  • malloc/free只是动态分配内存和释放内存,而new/delete在分配和释放内存的时候还会调用构造函数和析构函数进行数据的初始化和清理工作
  • malloc/free需要手动计算大小(使用sizeof好习惯),成功返回void*;new/delete可以自己计算类型大小,成功返回对应类型的指针
1 0
原创粉丝点击