首先,什么叫动态申请内存空间:说白了除了C99以外是没有可变数组这个概念的,这就导致我们在申请空间时造成很多的不方便,申请大了造成空间的浪费,小了还不够用。
而动态申请则解决了这个麻烦,他能够灵活的申请所需的空间,所申请的空间在堆区。
c语言_malloc/free
malloc和free都是函数
头文件:include<malloc.h>
原型:void* malloc(size_t _Size);
语法:指针 = (指针类型)malloc(创建大小,注意是以字节为单位);
举例:int *p = (int*)malloc(sizeof(int));
#include<stdio.h>
#include<malloc.h>
typedef struct A{
int a;
}A;
int main() {
int n;
scanf("%d", n);
//内置类型
int* p = (int*)malloc(sizeof(int));//int类型
int* array = (int*)malloc(sizeof(int) * n);//长度为n的数组
//自定义类型
A* p1 = (A*)malloc(sizeof(A));
free(p);
free(array);
free(p1);
}
C++_new/delete
new和delete是关键字
内置类型:
类型* 变量名=new 类型;//未初始化
类型* 变量名=new 类型(为空间数据赋值);//初始化
delete 变量名;
举例:int* p = new int;
int*p = new int(8);
delete p;
数组:
类型* 变量名=new 类型[填写开辟个数的数字];
类型* 变量名=new 类型[填写数字]{为空间内的多个数据赋值};
delete []p;
举例:int* p = new int[3];
int*p = new int[3]{1,2,3};
delete[] p;
#include<iostream>
using namespace std;
int main() {
int* p = new int;
int* p1 = new int(1);
int* pp = new int[3];
int* pp1 = new int[3]{1, 2, 3};
cout << "p:" << *p << endl;
cout << "p1:" << *p1 << endl;
cout << "pp:" << *pp<<(*pp)+1<<(*pp)+2 << endl;
cout << "pp1:" << *pp1<<(*pp1)+1<<(*pp1)+2 << endl;
delete p;
delete p1;
delete[] pp;
delete[] pp1;
}
自定义类型:
可见new调用了自定义类型的构造函数
delete调用了析构函数
既然有了malloc和free,new和delete的意义何在?
1.对于上面的内置类型,他们的效果是一样的
2.对于自定义类型,效果就不一样,malloc只申请空间,new申请空间+构造函数初始化
free只释放空间,delete 析构函数+释放空间
operator new/operator delete(了解)
operator new的效果跟malloc看起来相同
但是其实他在malloc(创建空间)的基础上添加了抛出异常机制,如果开创的空间过大malloc运行出错,operator则爆出警告终止程序
他相当于介于malloc和 new之间的产物:
- operator new = malloc+失败抛异常(这个就是为了new产生的,相当于中间)
- new = operator new +构造函数(operator new调用malloc因为malloc创建空间,然后new 调用operatornew)
- delete比起free不一样的地方:1.调用析构函数
- 但是他俩都是调用失败就退出程序,没有抛异常Operator delete和free没有区别
malloc和new的区别:
- 概念性质:malloc是一个函数,new是一个操作符
- 使用方法:参数传字节数,返回值是void*,new后面跟申请对象的类型,返回值是类型的指针
- 使用效果:new会调用构造函数,失败抛异常,malloc失败了返回0
内存泄漏
概念:p指向的空间不需要了,忘记或其他原因没有释放p指向的空间,就内存泄漏
危害:长期运行的程序出现内存泄漏,影响很大,如操作系统、后台服务等等,出现
内存泄漏会导致响应越来越慢,最终卡死。