C/C++ malloc和new

malloc和new

若想在堆区开辟空间时,C是使用malloc函数,而在C++则是使用new关键字。那么,C中的malloc和new有什么区别呢?这也是在面试时常见的问题。

目录
一、malloc和new的基本用法
二、自由存储区&堆的概念
三、malloc的实现方式
四、new的实现方式


一、malloc和new的基本用法

malloc: 它是C语言的一个函数,主要是在堆区申堆区请一块指定大小(由开发者指定)的内存空间,由开发者自己管理那一块内存空间。如下:

int *p = (int*)malloc(sizeof(int));

这里的意思是:在堆区申请一块长度为int字节的内存空间,这里可以使用字面变量,但是不建议,因为很危险,然后malloc返回出开辟后的空间,它返回的是void*类型,所以这里我们强转为自己想要的类型。


new: C++中开辟空间的关键字,主要作用是在自由存储区申请一块内存空间,申请一块内存空间。如下:

int *p = new int(20);

上面的意思是:在自由存储区申请一块长度为int的内存空间,里面存放着值为20。

从宏观上看,这就相当于C++中的bool类型和Java中的boolean类型一样,都是实现同样的功能,这是它们本质的作用,但是往跟深的看那还有有很多不一样的。malloc和new都是自己开辟内存空间,自己管理释放,相对的配套使用则是free()函数和delete关键字。其中free函数是用来释放malloc申请的空间,而delete是释放new开辟的空间。



二、自由存储区&堆的概念

在某些教材中,C++的分区模块是四大部分:代码区、全局区、栈区、堆区。这样说也没错,但实际上还有一个分区:自由存储区(free store)。关于对自由存储区的解释:自由存储是C++中通过new和delete动态分配和释放对象的抽象概念,通过new来申请的内存区域可称为自由存储区。而堆(heap) 是C语言和操作系统的一个术语,堆是操作系统所维护的一块特殊内存,它提供了动态分配的功能。我们可以用土办法来下面代码输出的结果:

int* p = (int*)malloc(4);
cout << "malloc = " << p << endl;
p = (int*)malloc(4);
cout <<"malloc = " << p << endl;

int* p2 = new int(50);
cout << "new = " << p2 << endl;
int *p3 = new int(100);
cout << "new = " << p3 << endl;

运行结果为:
运行结果
可以发现两个malloc出来的地址和new出来的不太一样,这是因为C++使用的区域是自由存储区。关于自由存储区的来历,它是C++在堆上建立的一块区域,其中就是供new来使用。但是需要注意:自由存储区并不等价于堆区,这一点是不能弄混的,不能说自由存储区建立在堆区上那就是堆了。



三、malloc的实现方式

malloc的实现方式是将堆的特定段空间申请出来,然后供开发者使用,我们以下面这个为示例:

int* p = (int*)malloc(sizeof(int));

上面说过。malloc是个函数,sizeof(int)表示申请的空间大小,之后返回void*类型的地址,这里转为int类型的地址,这一步一定要转类型,否则有可能出现乱码,例如下面这种情况:

void* p = malloc(sizeof(char));
char* ch = (char*)p;
*ch = 'a';
cout << ch << endl;

输出结果:a葺葺葺葺葺輯竱1,反正就是乱码。




四、new的实现方式

new关键字的实现方式是申请一块特定的区域给某个类型,而且更智能,而非malloc那么繁琐,语法上也更加简单也更智能,并且支持重载。C++底层源码中它是这么写的:
new关键字底层代码
这是编译器提供的底层和重载,可以看见它还重载了[],保证在创建数组的时候能使用,我们也可以自己重载。它在申请内存时分为三部分:
1、调用operator new
2、编译器运行相应的构造函数以构造数据类型,并为其传入初值。
3、对象构造完成后,返回一个指向该数据类型的指针。

注意:当我们重载new的时候,它存放的地方是由我们指定的。在众多C++编译器中,有部分编译器new关键字在底层的写法就是采用malloc来实现,这就是上面所说的有些教材说new是建立在堆区的。

  • 4
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值