C语言与C++中动态申请内存空间的详解:malloc/free与new/delete的使用方法
首先,什么叫动态申请内存空间呢?简单来说,除了 C99 之外,并没有可变数组这个概念。这就使得我们在申请空间时遇到很多不便之处,比如申请得大了就会造成空间的浪费,而申请得小了又不够用。

动态申请解决了这个麻烦。它可以灵活地申请所需的空间,并且所申请的空间位于堆区。
c语言_malloc/free
malloc和free都是函数
头文件:include
malloc 函数接收一个 size_t 类型的参数 _Size,并返回一个 void* 类型的指针。
指针是通过以下方式进行创建的:指针 = (指针类型)malloc(创建大小,需注意是以字节为单位);
定义一个整型指针 p,通过 malloc 函数分配一块大小为 sizeof(int) 的内存空间,并将其强制转换为整型指针类型赋值给 p 。
#include
#include
typedef struct A{
int a;
}A;
int main() {
int n;
scanf("%d", n);
//内置类型
使用 malloc 函数分配一个 int 类型大小的内存空间,并将其地址赋值给指针 p 。
创建一个长度为 n 的数组,通过 malloc 函数分配内存空间,将分配的内存地址强制转换为 int* 类型并赋值给 array 指针。
//自定义类型
A 指针 p1 分配了一块大小为 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 类型[填写开辟个数的数字];
类型 变量名被初始化为新的类型,其中包含填写数字个元素,这些元素用于为空间内的多个数据进行赋值。
delete []p;
举例:int* p = new int[3];
int*p = new int[3]{1,2,3};
delete[] p;
#include
using namespace std;
int main() {
int* p = new int;
int* p1 = new int(1);
int* pp = new int[3];
创建一个整型指针 pp1,使用 new 运算符分配了一个包含 3 个元素的整型数组,并初始化这些元素为 1、2、3。即 pp1 指向了一个包含 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.对于上面的内置类型,他们的效果是一样的
对于自定义类型而言,其效果存在差异。malloc 仅仅申请空间,而 new 既申请空间又进行构造函数初始化。
free只释放空间,delete 析构函数+释放空间
了解 operator new 和 operator delete 。 它俩分别用于动态内存的分配和释放。在 C++ 编程中,当需要在运行时动态地分配内存时,就会使用 operator new 。而当不再需要某个动态分配的对象所占的内存时,就会调用 operator delete 来释放该内存。
operator new的效果跟malloc看起来相同
但是实际上他在进行 malloc(创建空间)这个操作的基础之上添加了抛出异常的机制。如果所开创的空间过大,导致 malloc 运行出现错误,那么 operator 就会爆出警告并终止程序。
他相当于介于malloc和 new之间的产物:
在使用效果方面:new 会调用构造函数,若失败会抛异常;而 malloc 失败时返回 0 ,同时存在内存泄漏的情况。
概念:p 所指向的空间不再需要,但由于忘记或其他原因而未释放该空间,这就会导致内存泄漏。
危害在于长期运行的程序会出现内存泄漏,这带来的影响很大,像操作系统以及后台服务等都会出现这种情况。
内存泄漏会导致响应越来越慢,最终卡死。