C/C++动态内存管理

来源:互联网 发布:安徽自考网络助学加分 编辑:程序博客网 时间:2024/06/14 19:33

一、总结并剖析malloc/free和new/delete之间关系和差异。

malloc/free

1.函数原型及说明:
void* malloc(long NumBytes):该函数分配了NumBytes个字节,并返回指向这块内存的指针。如果分配失败,则返回一个空指针(NULL)。

void free(void *FirstByte):该函数是将之前用malloc分配的空间还给操作系统,也就是释放了这块内存,让它重新获得自由。

2.内存操作:
malloc函数的参数是接受需要分配的内存字节数,如果内存能够满足请求量,那么将会返回:指向被分配的内存块起始位置

free函数释放的是指针指向的内存(不是释放的指针本身,不会删除指针本身),其中,指针必须指向所释放内存空间的首地址。

new/delete

1.new和delete都是操作符。

2.操作时发生事件:
new的时候会有两件事发生:
1).内存被分配(通过operator new函数).
2).为被分配的内存调用一个或者多个构造函数构建对象.

delete的时候也会有两个事发生:
1).为被释放的内存调用一个或者多个析构函数.
2).释放内存(通过operate delete函数)

注意:使用delete时未加括号,delete便假设删除对象是单一对象。否则便假设删除对象是一个数组。因此,如果在调 `delete时也使用[] (new和delete使用[]时成对使用)。

malloc/free和new/delete的本质区别:

不同点:

1.malloc/free是c/c++语言的标准库函数,new/delete是c++的运算符。

2.new能够自动分配空间大小,new/delete是可以重载的,重载之后就变成了函数。

3.malloc在申请内存的时候,必须提供申请的长度,而返回的指针是void*型,必须要强转才能成为所需要的类型。

4.对于用户自定义的对象而言,用maloc/free无法满足动态管理对象的要求。对象在创建的同时要自动执行构造函数,对象在消亡之前要自动执行析构函数。
由于malloc/free是库函数而不是运算符,不在编译器控制权限之内,不能够把执行构造函数和析构函数的任务强加于malloc/free。
因此C++需要一个能对对象完成动态内存分配和初始化工作的运算符new,以及一个能对对象完成清理与释放内存工作的运算符delete—简而言之 new/delete能进行对对象进行构造和析构函数的调用进而对内存进行更加详细的工作,而malloc/free不能。

相同点:

1.都必须配对使用,在作用域内,new/malloc所申请的内存,必须被有效释放

2.都是申请内存释放内存,free和delete可以释放NULL指针。

注:C++程序经常要调用C函数,而C程序只能用malloc/free管理动态内存。如果用free释放“new创建的动态对象”,那么该对象因无法执行析构函数而可能导致程序出错。如果用delete释放“malloc申请的动态内存”,理论上讲程序不会出错,但是该程序的可读性很差。所以new/delete,malloc/free必须配对使用。

二、剖析new/delete、new[]/delete[]到底做了些什么事情.

new/delete

在使用new的时候做了两件事:
1.调用operator new 分配空间。
2.调用构造函数初始化对象。

在使用delete的时候也做了两件事情:
1.调用析构函数清理对象。
2.调用operator delete函数释放空间。

new []/delete[]

在使用new[N]的时候也做了两件事:
1.调用operator new分配空间。
2.调用N次构造函数初始化N个对象。

在使用delete[]的时候也做了两件事:
1.调用N次析构函数清理N个对象。
2.调用operator delete函数释放空间.

这里写图片描述

三、实现NEW_ARRAY/DELETE_ARRAY宏,模拟new[]/delete[]申请和释放数组。

//模拟new[]#define NEWARRAY(PTR, TYPE, N)                                     do                                                         {                                                              PTR = (TYPE*)operator new(sizeof(TYPE)*N + 4);         (*(int*)PTR) = N;                                     PTR = (TYPE*)((char*)PTR + 4);                         for (size_t i = 0; i < N; ++i)                              new(PTR + i)TYPE;                         } while (false);  //模拟delete[]  #define DELETEARRAY(PTR, TYPE)         do                                      {                                          size_t N = *((int*)PTR - 1);       for (size_t i = 0; i < N; ++i)         PTR[i].~TYPE();           PTR = (TYPE*)((char*)PTR - 4);      operator delete(PTR);          } while (false);

“`

原创粉丝点击