C/C++动态内存管理

1:总结并剖析malloc/free和new/delete之间关系和差异。
mallloc和free分别用于执行动态内存的分配和释放

void *malloc(size_t,size);
void free(void pointer);

malloc分配的是一块连续的空间,如果操作系统无法向malloc提供更多的内存空间,malloc就返回一个NULL,malloc的返回值是void*,free的参数必须要么是NULL,要么是malloc realloc,或calloc的返回值.
callloc和reallc
calloc与malloc区别在于calloc在返回指向内存的指针之前把它初始化为0。

void  *calloc(size_t num_elements,size_t element_size)
void  realloc(void *ptr,size_t new size)

realloc用于修改原先已经分配的内存块的大小,如果原先内存块无法改变大小,realloc将分配一块正确大小的内存,并把原先那块内存上的内容复制到新的快上因此在使用realloc后就不能在使用指向旧内存的指针而应该用realloc所返回的新指针。
如果realloc的第一个参数是NULL,它的内存等同malloc;

 int* p3 = (int*) realloc(p2 , sizeof( int)*6);

这里p2不需要释放
·常见动态内存错误
(1)对NULL指针进行解引用操作(2)对分配的内存操作时越过边界 ,释放并非动态分配的内存(3)试图释放一块动态分配的内存的一部分,以及一块动态内存被释放之后继续被使用
C++通过new和delete动态管理内存。

void Test () 
{     
int* p4 = new int;         // 动态分配4个字节(1个 int)的空间单个数据     
int* p5 = new int(3);      // 动态分配4个字节(1个 int)的空间并初始化为3          
int* p6 = new int[3]      // 动态分配12个字节(3个 int)的空间
     delete p4 ;
     delete p5;     
     delete[] p6;
}

!!!一定要注意匹配使用
全局变量、全局静态变量、局部静态变量、局部变量之间的区别是什么?
局部变量与其它三个有本质区别。
局部变量,定义在函数内,作用域为定义位置,到所在大括号结束。 每次执行到定义语句的时候,系统为该变量分配内存,当作用域结束后,内存被释放。

而另外三个,都是在系统运行时就分配内存,在运行过程中都不会释放,直到程序结束。
也就是说,局部变量和其它三个,最明显的区别:
· 生命周期不同
· 分配时间不同
· 分配位置不同。
而另外三个,在这几项上是相同的,之间的区别在于作用域。
全局变量,作用域为整个项目,不管在哪个文件中,只要声明后都可以使用。
静态全局变量,作用域为定义改变量的所在文件。
而静态局部变量,作用域与普通局部变量一样,都是定义位置到所在大括号结束。
这里写图片描述
·在C++中,申请动态内存与释放动态内存,用new/delete与malloc/free都可以;而且它们的存储方式相同,new/malloc动态申请的内存都位于堆中,无法被操作系统自动回收,需要对应的delete/free来释放空间。此外,对于一般的数据类型,如int、char,它们的效果是一样的。
·malloc/free是C/C++语言的标准库函数,new/delete是C++的运算符。对于类的·对象而言,malloc、free无法满足动态对象的要求。在对象创建的同时要自动执行构造函数,对象消亡之前要自动执行析构函数,而malloc/free不在编译器控制权限之内,无法执行构造函数和析构函数
·new能够自动计算所开辟内存空间的大小,而malloc需要手动计算内存空间的大小
·new/delete直接带具体类型的指针,malloc/free返回void类型的指针。
·new一般由两步构成,分别是new操作和构造。new操作对应于malloc,但new操作可以重载,可以自定义内存分配策略,不做内存分配,甚至分配到费内存设备上,而malloc不可以。
·new将调用构造函数,而malloc不能;delete将调用析构函数,而free不能。
·malloc/free需要库文件stdlib.h支持,new/delete则不需要库文件支持。
2:剖析new/delete、new[]/delete[]到底做了些什么事情。
在使用new的时候做了两件事:
调用operator new分配空间
调用构造函数初始化对象

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

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

在使用delete[]的时候也做了两件事:
调用N次析构函数清理N个对象
调用operator delete函数释放空间
这里写图片描述

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

模拟实现NEW_ARRAY
#define NEW_ARRAY(P, TYPE, N) \
    do{                                                 \
        int* P_NEW = (int*)malloc(sizeof(TYPE)*N + 4);  \
        ((int*)P_NEW)[0] = N;                           \
        P = (TYPE*)(P_NEW + 1);                         \
        int I_NEW = 0;                                  \
        for (; I_NEW < N; I_NEW++)                      \
            new(P + I_NEW)TYPE;                         \
    } while (false);

模拟实现DELETE_ARRAY
#define DELETE_ARRAY(P, TYPE) \
    do{\
        int n = *((int*)P - 1); \
        while (n--)\
        (P[n]).~TYPE(); \
        free((int*)P - 1); \
    } while (false);
   模拟实现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;                       
模拟实现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);                                             
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值