C/C++内存分配malloc/free, new/delete

c中malloc和free是函数,包含在stdlib.h头文件中,分配成功返回指针,失败返回空指针。

与new的区别是:
1,malloc与free是C++/C语言的标准库函数,new/delete是C++的运算符。它们都可用于申请动态内存和释放内存。
2,对于非内部数据类型的对象而言,光用maloc/free无法满足动态对象的要求。对象在创建的同时要自动执行构造函数,对象在消亡之前要自动执行析构函数。由于malloc/free是库函数而不是运算符,不在编译器控制权限之内,不能够把执行构造函数和析构函数的任务强加于malloc/free。
3,因此C++语言需要一个能完成动态内存分配和初始化工作的运算符new,以一个能完成清理与释放内存工作的运算符delete。注意new/delete不是库函数。
4、new以具体类型为单位进行内存分配,malloc以字节为单位进行内存分配。
5、C++程序经常要调用C函数,而C程序只能用malloc/free管理动态内存。
6、new在申请单个类型变量时可进行初始化,malloc不具备内存初始化的特性
int* pi = new int(1);
float* pf = new float(2.0f);
char* pc = new char(‘c’);
在这里插入图片描述

一、为什么需要动态内存分配?
在C++程序中,所有内存需求都是在程序执行之前通过定义所需的变量来确定的。 但是可能存在程序的内存需求只能在运行时确定的情况。 例如,当需要的内存取决于用户输入。 在这些情况下,程序需要动态分配内存,C ++语言将运算符new和delete合成在一起。

(1)特点
1.C++中通过new关键字进行动态内存申请
2.C++中的动态内存分配是基于类型进行的
3.delete关键字用于内存释放
(2)语法
①变量申请:
Type* pointer = new Type;
//…
delete pointer;
表达式用于分配内存以包含一个类型类型的单个元素。

②数组申请:
Type* pointer = new Type[N];
//…
delete[] pointer;
表示用于分配类型类型的元素的块(数组),其中N是表示这些元素的量的整数值。

Example:
int * foo;
foo = new int [5];
在这种情况下,系统为int类型的五个元素动态分配空间,并返回指向序列的第一个元素的指针,该指针被分配给foo(指针)。 因此,foo现在指向一个有效的内存块,其中包含五个int类型元素的空间。

这里,foo是一个指针,因此,foo指向的第一个元素可以使用表达式foo [0]或表达式* foo(两者都是等价的)来访问。可以使用foo [1]或*(foo + 1)访问第二个元素,依此类推…

Note:
我们程序请求的动态内存由系统从内存堆中分配。 但是,计算机内存是一种有限的资源,它可能会耗尽。 因此,无法保证所有使用operator new分配内存的请求都将由系统授予。

四、C++动态分配内存异常机制
事项一下,我们的计算机内存优先,如果我们分配一个很大的内存空间,会出现栈满,程序产生异常,程序崩溃。所以我们需要引入异常机制。
C ++提供了两种标准机制来检查分配是否成功。
(1)一个是处理异常。
使用此方法,在分配失败时抛出bad_alloc类型的异常。 例外是这些教程后面解释的强大的C ++特性。 但是现在,您应该知道如果抛出此异常并且未由特定处理程序处理,则程序执行将终止。
此异常方法是new默认使用的方法,并且是在声明中使用的方法,like:
foo = new int [5]; // if allocation fails, an exception is thrown

(2)另一种方法称为nothrow
当使用它时会发生的情况是,当内存分配失败时,而不是抛出bad_alloc异常或终止程序,new返回的指针是空指针,程序继续正常执行 。
可以使用名为nothrow的特殊对象(在header 中声明)作为new的参数来指定此方法:
foo = new (nothrow) int [5];
在这种情况下,如果此内存块的分配失败,则可以通过检查foo是否为空指针来检测异常:
int * foo;
foo = new (nothrow) int [5];
if (foo == nullptr) {
// error assigning memory. Take measures.
}

你可能感兴趣的:(C/C++内存分配malloc/free, new/delete)