【C++】内存管理方式

来源:互联网 发布:mysql with cube 编辑:程序博客网 时间:2024/05/16 22:18

本篇博文旨在介绍C++的内存管理方式,并和C语言中的内存管理方式作出对比;说明了C语言中的malloc/free和C++中的new/delete的区别;介绍了定位new表达式,来模拟实现new和delete


C中的内存管理方式

堆上创建空间

malloc来申请空间,需要自行free进行释放

除了malloc外,还有calloc,realloc来申请

他们都需要free进行释放,否则会造成内存泄漏

栈上创建空间

编译器会自己在栈上动态开辟内存,利用_alloc来开辟,并自主进行维护

C语言中常见的几种内存泄漏

情况1:忘记了释放

//去做其他事情了,忘记了释放void FunTest1(){int* pTest = (int*)malloc(10 * sizeof(int));assert(pTest != NULL);//do other thing//...忘记了释放}

情况2:逻辑出错

//程序逻辑不清晰,以为释放了,却没有释放void FunTest2(){int* pTest1 = (int*)malloc(10 * sizeof(int));int* pTest2= (int*)malloc(10 * sizeof(int));//do other things//...pTest1 = pTest2;//...//do other things//内存泄漏,现在pTest1和pTest2指向的是同一块空间//原来pTest1申请的空间没有释放free(pTest1);free(pTest2);//错误,释放出错}

情况3:申请的空间被错误的使用

//程序的错误操作,导致了堆的破坏void FunTest3(){char* pTest = (char*)malloc(sizeof(char)* 5);strcpy(pTest,"Memory Leaks");free(pTest);//错误,申请的内存被破坏,释放出错}

情况4:释放的地址与申请的地址不一致

//释放时,地址被修改,与申请的地址不一致void FunTest4(){int* pTest = (int*)malloc(sizeof(int)* 10);assert(pTest);pTest[0] = 0;pTest++;//do other thingsfree(pTest);//错误,释放出错}

C++中的内存管理方式


内存组织结构

全局变量、全局静态变量、局部静态变量、局部变量存储位置的区别


C语言中的malloc/free和C++中的new/delete的区别和联系

相同点:

它们都是对内存进行管理

区别:

区别1:类型

malloc/free是函数,而new/delete是关键字、操作符

区别2:作用

malloc/free只是简单的进行内存的申请和释放;new/delete除了进行内存申请和释放,还会调用对象的构造函数和析构函数进行空间的初始化和清理

区别3:参数与返回值

malloc/free需要手动计算申请内存的空间大小,而且返回值是void*,需要自己转换成所需要的类型;

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);

说明:

1、operator new/operator delete  operator new[]/operator delete[] 和malloc/free的使用方法一样

2、它们只会进行内存的申请和释放,不会调用对象的构造函数和析构函数

3、operator new/operator delete 只是对malloc/free的一层封装

operator new/operator delete operator new[]/operator delete[] 和new/delete 区别

new 的作用

调用operator new进行内存的事情

调用构造函数初始化空间

delete 的作用

调用析构函数清理空间

调用operator delete释放空间

new[]的作用

调用N次operator new进行内存的申请

调用构造函数进行初始化

delete[] 的作用

调用析构函数对空间进行清理

调用N次operator delete释放空间

定位new表达式

所谓定位new表达式,就是利用malloc/free函数+new表达式/析构函数来模拟new和delete的行为

malloc函数申请空间后,利用定位new表达式显示调用构造函数来模拟new的功能

然后显示的调用析够函数,最后用free释放来模拟delete的功能

//定位new表达式//在用malloc已分配的空间中调用构造函数初始化一个对象class Array{public:Array(size_t size = 10):_size(size), _a(0){cout << "Array()" << endl;if (_size > 0){_a = new int[_size];}}~Array(){cout << "~Array()" << endl;if (_a){delete _a;_a = NULL;_size = 0;}}private:int* _a;size_t _size;};void Test(){//malloc/free+new()/析构函数 模拟new和delete的行为//模拟newArray* p1 = (Array*)malloc(sizeof(Array));new(p1)Array(100);//模拟deletep1->~Array();free(p1);//模拟new[]Array* p2 = (Array*)malloc(sizeof(Array)*10); for (size_t i = 0; i < 10; ++i){new(p2 + i)Array;}//模拟delete[]for (size_t i = 0; i < 10; ++i){p2[i].~Array();}free(p2);}

1 0
原创粉丝点击