乐趣区

关于c++:C-new和delete运算符

一、前言

学习过 C 语言会晓得,在 C 语言中,动静分配内存用 malloc()函数,开释内存用 free()函数。在 C ++ 中这 2 个函数还是能够应用的,然而 C ++ 新增了 2 个关键字:new 和 delete。new 用来动静分配内存,delete 用来开释内存。咱们能够这样应用:

int* p = new int;
delete p;
或
int* pArray= new int[20];
delete[] pArray;

new 操作符会依据前面的数据类型来推断所需空间的大小。由上可知,应用 new 调配的内存用 delete 开释,应用 new[]调配的内存用 delete[]开释,它们是一一对应的。
new 申请空间时会多申请 4 个字节,用于寄存对象的个数,在返回地址时则会向后偏移 4 个字节,在 delete 时则会查看内存上对象的个数,依据个数确定调用几次析构函数,这样能力齐全清理所有对象占用的内存,因而对于内置类型若 new[],应用 delete 开释,没有影响;但若是自定义类型,应用 delete 开释时只会调用一次析构函数,就会存在有对象没有被析构的状况。

new 是在自在存储区上分配内存 (能够在堆上,也能够在动态存储区上,取决于 operator new 实现细节,取决与它在哪里为对象调配空间),必须手动开释,否则只能等到程序运行完结由操作系统回收。为了防止内存透露,new 和 delete、new[] 和 delete[] 操作符应该成对呈现,并且不要和 C 语言中 malloc()、free() 一起混用。
在 C ++ 中最好应用 new 和 delete 治理内存,比 C 语言的 malloc 和 free 多了能够主动调用构造函数和析构函数,这样在程序运行完结时能够开释内存。

二、new、delete 和 malloc、free 的区别

1、new 和 delete

new 在操作时,内存通过 operator new 函数被调配,而且会为被调配的内存调用一个或多个构造函数构建对象;new 内置了 sizeof、类型转换和类型安全检查性能,对于非外部数据类型的对象而言,new 在创立动静对象的同时实现了初始化工作。如果对象有多个构造函数,那么 new 的语句也能够有多种形式。如:

int *p= new int[100](1);// 创立 100 个动静对象的同时赋初值 1 

delete 时,会为将被开释的内存调用一个或多个析构函数,还会通过 operator delete 函数开释内存。

2、malloc 和 free

malloc 的函数原型为

void *malloc(long NumBytes)

由原型可知,调用 malloc 时须要 指定分配内存的字节数,胜利调配的话就返回对应的指针,指向被调配的内存块起始地位;否则返回空指针。

free 的函数原型为:

void free(void *p)

将之前用 malloc 调配的空间还给程序或者操作系统,即对 malloc 申请的内存空间进行开释。
free 函数开释的是 指针指向的内存(不是开释的指针自身,不会删除指针自身), 其中指针必须指向所开释内存空间的首地址。如果 p 不是 NULL 指针,那么 free 对 p 间断操作两次就会导致程序运行谬误。

3、本质区别

1)malloc/free 是 C /C++ 语言的规范库函数,new/delete 是 C ++ 的运算符
2)new 能够主动分配内存空间,malloc 须要指定申请空间的大小
3)对于用户自定义的对象而言,malloc/free 无奈满足动静治理对象的要求。因为 malloc/free 是库函数而不是运算符,不再编译器管制权限之内,不可能把执行构造函数和析构函数的工作强加于 malloc/free。

new/delete 能够被重载,malloc/free 不能够;
new/delete 底层是基于 malloc/free 实现的;
malloc 分配内存之后发现不够,可通过 realloc 函数对其进行裁减或放大;

malloc 申请内存时返回内存地址要查看判空,因为申请失败时返回 NULL;new 不必判断,在内存调配失败时会抛出异样 bac_alloc,因而可在 new 时加上异样解决机制,如:

int* p = new(std::nothrow) int[10];

为什么还保留了 malloc 和 free?C++ 程序常常要调用 C 函数,而 C 程序 只能用 malloc/free 治理动态内存。若应用 free 开释 new 创立的动静对象,对象会因无奈执行析构函数而导致程序出错。若 delete 开释 malloc 申请的动态内存,可能不会出错,但程序的可读性差。

退出移动版