定义与使用:
malloc()和free()函数:
动态内存分配(申请一块连续的指定大小的内存区域,以void *类型返回分配的内存区域地址)与释放函数(释放malloc函数给变量分配的内存空间)。C++/C语言的标准库函数。
void *malloc(size_t size);
void free (void *memblock);
int *pC =(int *)malloc(sizeof(int));//申请
*pC = 1; //使用
free(pC); //释放
new和delete:
动态内存分配和内存释放,C++的运算符、关键字。
new在申请内存时返回是指定类型的指针,申请内存大小自动计算;
delete+动态内存的指针
int *pCpp = new int; //申请
*pCpp = 2; //使用
delete pCpp; //释放
//new申请与释放二维数组
int** p = new int*[10]; //arr[10][10]二维数组
//new申请
for (int i = 0; i < 10; i++)
{
p[i] = new int[10];
}
//delete释放
for (int i = 0; i < 10; i++)
{
delete[] p[i];
}
delete[] p;
关于new和new[]、delete 和 delete[](底层做的工作):
1.new T类型(自定义类型)
(1)调用operator new(sizeof(T)),该函数的函数原型为void* operator new(size_t size)。
(2)调用operator new中的malloc(set_new_handle),如果申请成功,返回;申请失败(可能原因是内存空间不足),采取应对措施set_new_handler,如果应对措施没有,抛出一个异常。
(3)调用一个构造函数。构造函数显示给出,编译器自动合成。
2.delete p
(1)调用一个析构函数。
(2)调用operator delete,释放空间地址。
(3)调用free函数。
3.new T[N]
(1)调用operator new[] (N*sizeof(T)),会在申请的空间的头部多给4个字节的空间,用来存放N。
(2)调用operator new函数
(3)调用malloc函数
(4)调用N次构造函数,构造出来N个对象。
(5)返回第一个对象所在的首地址,不是原空间的地址,而是原空间的地址向后偏移4个位置。
4.delete[] p
(1)取出N(在空间的前四个字节中)。
(2)调用N次析构函数。
(3)调用operator delete[] (p)。
(4)调用operator delete。
(5)调用free函数。
malloc()与new的区别:
1、性质不同:
malloc()与free()是库函数,需要头文件(#include <stdlib.h>)。
new与delete是C++关键字(运算符)。
2、形式不同:
malloc()需要申请的内存的大小(以参数形式传入),返回void * 指针;内存分配失败时,返回NULL(空指针)。
new申请的内存系统计算大小,返回指定类型。内存分配失败时,抛出bac_alloc异常。
3、内存开辟区域不同:
malloc()在堆上开辟内存。
new()在自由存储区为对象动态分配内存空间。(自由存储区:C++基于new操作符的抽象概念,有栈区有堆区)
int a = 10; //栈上开辟a的空间
char* p4 = new (&a) char('a'); //new返回类型强转为从a地址开始的char类型(使用a的空间)
4、自定义类型和重载:
malloc():库函数,无法强制要求其做自定义类型对象构造和析构,且不允许重定义。
new():调用operator new()函数,申请足够内存(通常底层malloc实现),然后调用类型的构造函数,初始化成员变量,最后返回自定义类型指针。delete先调用析构函数,然后调用operator delete()函数释放内存。
C++允许重载new/delete操作符(如new不需要为对象分配内存,而是指定一个地址作为内存起始区域,new在这段内存上为对象调用构造函数完成初始化,并返回此地址)。