malloc()/free()是C语言的标准库函数,new/delete是C++的运算符,它们都可用于申请动态内存和释放内存,new/delete在实现上其实调用了malloc()/free()函数,然后又做了一些其他封装,所以两者虽有相似却又有不同。

new与malloc()申请内存位置不同,new从自由存储区(free store)分配,而malloc()从堆区(heap)分配(请参考ISO14882内存管理部分),free store和heap很相似,都是动态内存,但位置不同,这就是为什么new出来的内存不能通过free()释放。

malloc()/free()

1
2
3
void *malloc(unsigned size); //申请size个字节的空间,返回首地址
void free(void *p); //释放以p为首地址的存储空间
//void *p 表示指向任意数据类型的指针
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include<stdio.h>
#include<stdlib.h>

int main(int argc, char const *argv[])
{
int *ptr;
int size=10;
ptr = (int *)malloc(size*sizeof(int)); //强制类型转换
for(int i = 0;i<15;i++)
{
*(ptr+i) = i;
}
for(int i = 0;i<10;i++)
{
printf("%d ",ptr[i]); //0 1 2 3 4 5 6 7 8 9
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
int main(int argc, char const *argv[])
{
int *ptr;
int size=10;
ptr = (int *)malloc(size*sizeof(int));
for(int i = 0;i<15;i++)
{
*(ptr+i) = i;
}
for(int i = 0;i<10;i++)
{
printf("%d ",ptr[i]); //0 1 2 3 4 5 6 7 8 9
}
printf("\n");
free(ptr); //C语言中的指针可以指向一块内存,如果这块内存稍后被操作系统回收(被释放),但是指针仍然指向这块内存,那么,此时该指针就是“悬空指针”。
for(int i = 0;i<10;i++)
{
printf("%d ",ptr[i]); //无输出
}

return 0;
}

1
void *realloc(void *p, unsigend size); //扩展以p为首地址的存储空间到size个字节
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
int main(int argc, char const* argv[])
{
int* ptr;
int size = 10;
ptr = (int*)malloc(size * sizeof(int));
for (int i = 0; i < 15; i++)
{
*(ptr + i) = i;
}
for (int i = 0; i < 10; i++)
{
printf("%d ", ptr[i]); //0 1 2 3 4 5 6 7 8 9
}
printf("\n");
ptr = (int*)realloc(ptr, 15 * sizeof(int));
for (int i = 10; i < 15; i++)
{
* (ptr + i) = i;
}
for (int i = 0; i < 15; i++)
{
printf("%d ", ptr[i]); //0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
}
return 0;
}

new/delete

在C语言中,动态分配内存时一般常使用malloc()函数,但是对于非内置数据类型(如struct、enum、class等),malloc()与free()无法满足动态对象的需求,因此C++引入new与delete关键字,用来进行内存申请与释放空间。

对于非内置类型对象而言,new/delete在创建对象时不止是分配内存,还会自动执行构造函数进行初始化,对象消亡之前自动执行析构函数,而malloc()/free()只能简单的分配释放内存。

malloc()函数申请内存时返回的是一个void*类型的指针,而new与malloc()不同,它分配一块存储空间并且指定了类型信息,并根据初始化列表中给出的值进行初始化,是直接可以使用的内存,这个过程,程序员常称之为new一个对象。

1
2
3
4
new 数据类型(初始化列表);
char *pc = new char; //申请一段空间用来存储char类型,内存中没有初始值
int *pi = new int(10); //申请一段空间存储int类型数据,初始值为10
double *pd = new double(); //申请一段空间存储double类型的数据,默认初始值为0

new也可以用来创建数组对象,其格式如下:

1
new 数据类型[数组长度];

用new运算符分配内存,使用后要及时释放以免造成内存泄露,C++提供了delete运算符来释放new出来的内存空间,其格式如下:

1
delete 指针名;

直接作用于指针就可以删除由new创建的对象,释放指针所指向的内存空间。但在释放数组对象时要在指针名前加上[],其格式如下:

1
delete []指针名;