猿创征文 |【C++】动态内存的分配与回收

文章目录

  • 一、回顾C中动态分配内存和回收的方式
  • 二、C++中动态分配内存和回收的方式
    • 2.1 分配
      • 2.1.1 单个空间的分配
      • 2.1.2连续空间的分配
    • 2.2 回收
      • 2.2.1 单个空间的回收
      • 2.2.2 连续的空间的回收
    • 2.3 举例说明
      • 2.3.1 单个空间的举例
      • 2.3.2 连续空间的举例
  • 三、自定义类类型中的new/delete
  • 四、new与delete的底层
  • 五、C++中new与malloc之间的联系与区别
    • 5.1 new与malloc之间的联系
    • 5.2 new与malloc之间的区别

一、回顾C中动态分配内存和回收的方式

C中动态分配内存的方式
1.malloc
2. calloc
3. realloc
回收方式
free

代码如下:

#include 
#include 

int main()
{
    int *p1=(int *)malloc(sizeof(int));
    printf("%d\n",*p1);//没有初始化
    int *p2=(int *)calloc(1,sizeof (int));
    printf("%d\n",*p2);//有初始化
    int *p3=(int *)realloc(p2,sizeof(int)*10);
    printf("%d\n",*p3);//有初始化
    free(p1);
    //free(p2);
    //同一块堆区空间被多次释放会造成doublefree的现象,程序就会异常中止。
    free(p3);
    return 0;
}

结果展示:
猿创征文 |【C++】动态内存的分配与回收_第1张图片
总结:

  1. malloc在堆上开辟空间并没有进行初始化。
  2. calloc在堆上开辟空间是有初始化。
  3. relloc在堆上开辟空间都是有初始化。
  4. 同一块堆区空间被多次释放会造成double free的现象,程序就会异常中止。

二、C++中动态分配内存和回收的方式

C++提供了新的关键字new来动态分配空间。
同时为了回收空间,又提供关键字delete来释放空间。
在C++中支持malloc/free,但是我们一般都使用 new/delete

2.1 分配

2.1.1 单个空间的分配

格式: 数据类型 *指针名 = new 数据类型;
如: int *p = new int;
在堆区分配 1 个 int 大小的空间。

2.1.2连续空间的分配

格式: 数据类型 *指针名 = new 数据类型[个数];
如: int *p = new int[5];
在堆区分配 5 个 int 大小的空间,连续的。

2.2 回收

2.2.1 单个空间的回收

delete 指针名;

2.2.2 连续的空间的回收

delete []指针名;
[]里面不用写长度,但是[]必须写,表示释放指针指向的连续空间。

2.3 举例说明

2.3.1 单个空间的举例

代码如下:

#include 
using namespace std;

int main()
{
    int *pa=new int;
    *pa=100;
    cout << *pa << endl;
	不初始化
    int *pb=new int;
    cout << *pb << endl;
	//用0初始化
    int *pc = new int();
    cout<< *pc <<endl;
    delete pc;

    int *pd=new int(521);
    cout << *pd << endl;

    delete pa;
    delete pb;
    delete pc;
    delete pd;
    return 0;
}

结果展示:
猿创征文 |【C++】动态内存的分配与回收_第2张图片

总结:

  1. new分配的空间如果没有初始化,是随机值。
  2. 当在类型后加上()时,new分配的空间如果没有初始化,会自动用 0 进行初始化。
  3. 我们使用new时,一般都是直接初始化的操作,可以使用括号的方式直接初始化,new后面的内置类型后加个括号表示编译器在括号取值初始化内置类型所开辟的内存中的值。
  4. delete pa;使用delete释放已经开辟的空间。

2.3.2 连续空间的举例

代码如下:

#include 
using namespace std;

int main()
{
    int *pa=new int[10];
    int i=0;
    for(i=0;i<10;i++)
    {
        cout << pa[i] << ",";
    }
    cout << endl;
    cout << "-----------------------------" << endl;
    for(i=0;i<10;i++)
    {
        *(pa+i)=i;
    }
    for(i=0;i<10;i++)
    {
        cout << pa[i] << ",";
    }
    cout << endl;
    cout << "-----------------------------" << endl;
    int *pb=new int[10]{1,2,3};
    for(i=0;i<10;i++)
    {
        cout << pb[i] << ",";
    }
    delete []pa;
    delete []pb;
    return 0;
}

结果展示:
猿创征文 |【C++】动态内存的分配与回收_第3张图片

总结:

  1. int *pa=new int[10];此种连续开辟空间,是没有初始化的。内存中的值有很多是随机值的。
  2. 可以采用循环,或者采用int *pb=new int[10]{1,2,3};这种方式进行初始化。这是C++11的新语法。
  3. 如果是连续空间的开辟,一定要要使用delete[]的方式来释放。

三、自定义类类型中的new/delete

针对于内置类型而言,new大体相当mallocdelete大体相当于free

但是如果自定义类类型
new代表两种含义:开辟空间,调用类中的构造函数进行初始化
delete也代表两含义:即调用类中的析构函数,然后再释放空间

关于构造与析构在之后的文章会详细讲解,感兴趣可以关注一下!

代码如下:

#include 
using namespace std;
struct Stu
{
    Stu()
    {
        cout << "Stu的构造" << endl;
    }
    ~Stu()
    {
        cout << "Stu的析构" << endl;
    }
};

int main()
{
    Stu *pstu=new Stu;
    delete pstu;
    return 0;
}

结果展示:
猿创征文 |【C++】动态内存的分配与回收_第4张图片

四、new与delete的底层

首先调用new
猿创征文 |【C++】动态内存的分配与回收_第5张图片
在底层调用的还是malloc分配的空间
猿创征文 |【C++】动态内存的分配与回收_第6张图片
malloc申请空间失败返回NULL;
new申请空间失败抛出一个异常;
猿创征文 |【C++】动态内存的分配与回收_第7张图片

五、C++中new与malloc之间的联系与区别

5.1 new与malloc之间的联系

new的底层就是用malloc实现的。

5.2 new与malloc之间的区别

  1. malloc如果申请空间失败返回NULL,new如果申请空间失败抛出异常 bad_alloc();
  2. new就是按类型开辟空间的,而malloc是按字节为单位开辟空间的。
  3. new/delete 是C++的关键字,malloc/free是库函数
  4. new可以在分配空间的同时进行初始化,malloc不可以。
  5. 当new分配的空间以int *pc = new int();,这种形式的时候,如果没有初始化,将用0进行初始化。如果是以int *pc = new int形式出现的,则将是随机值。
    malloc分配的空间如果没有初始化,是随机值,需要手动调用memset或者bzero函数来清空。
  6. new会根据类型自动计算分配空间的大小,malloc需要手动sizeof计算,传参。
  7. new是要什么类型,就返回什么类型的指针,malloc返回void *,需要进行强转。

对自定义类型来讲:

new 不仅开辟空间,还会调用自定类中的构造函数,malloc不会。
delete 不仅释放空间,还会在释放空间前先调用类中析构函数,free不会。

你可能感兴趣的:(C++,c++,c语言,开发语言,经验分享,猿创征文)