面试题:new与malloc动态分配内存的区别与联系

本文介绍了C++中动态内存分配的两种方式——malloc与new,详细阐述了它们的联系与区别。malloc是C语言库函数,需要指定内存大小且不支持初始化,而new是C++运算符,能自动计算类型大小并可进行初始化。new还可以重载,指定内存分配区域。在使用后,都需要配合free或delete释放内存,防止内存泄漏,并且释放后通常将指针置为空以避免野指针问题。
摘要由CSDN通过智能技术生成

C++中,动态分配内存常有两种方式,一是通过C语言中的malloc/free函数,二是c++本身的new/delete运算符。malloc和new之间有啥联系和区别呢,在编程中又该怎么使用呢,我们一起来看一下。

一、malloc与new介绍

malloc原理

malloc 函数的实质是它有一个将可用的内存块连接为一个长长的列表的所谓空闲链表。 调用 malloc()函数时,它沿着连接表寻找一个大到足以满足用户请求所需要的内存块。(如果没有搜索到,那么就会用sbrk()才推进brk指针来申请内存空间)。 然后,将该内存块一分为二(一块的大小与用户申请的大小相等,另一块的大小就是剩下来的字节)。 接下来,将分配给用户的那块内存存储区域传给用户,并将剩下的那块(如果有的话)返回到连接表上。 调用 free 函数时,它将用户释放的内存块连接到空闲链表上。 到最后,空闲链会被切成很多的小内存片段,如果这时用户申请一个大的内存片段, 那么空闲链表上可能没有可以满足用户要求的片段了。于是,malloc()函数请求延时,并开始在空闲链表上检查各内存片段,对它们进行内存整理,将相邻的小空闲块合并成较大的内存块。(参考博客:c/c++中malloc的底层实现原理。)
malloc:C语言提供的库函数,用于在堆区中申请一块指定大小的内存,并返回指向内存首地址的无类型指针;
new:C++语言提供的运算符,由编译器在自由存储区自动分配对象应占的内存,并返回指向内存首地址的对象类型指针;

二、联系

 1、二者均是动态分配内存的方法,由程序员自动开辟和释放内存,需要malloc/free、new/delete成对使用;
 2、new是以malloc函数为底层来实现的;

三、区别

 1、malloc是C语言定义的库函数,而new是C++定义的运算符;
 2、malloc必须由程序员指定分配内存的大小,而new由编译器自动计算指定类型的内存大小,因此malloc不能对类进行操作而new可以;
 3、malloc不能进行初始化,new可以进行初始化;
 4、malloc的返回类型是viod*指针(需要强转换为所需要的类型),而new的返回类型是对象类型的指针;
 5、malloc不能重载,而new可以重载operator new,可以指定内存分配的区域 ;

四、常见用法

1、malloc/free

malloc的函数原型为:void* malloc(size_t size);
free的函数原型为:void free(void* ptr);

一起看一下malloc/free的使用案例:

#include<iostream>
using namespace std;

int main()
{
	int len=3;
	int* p = (int*)malloc(sizeof(int) * len); //分配3个int元素数组的内存

	p[0] = 10;  //初始化数组的第一个元素
	p[1] = 20;  //初始化数组的第二个元素
	p[2] = 30;  //初始化数组的第三个元素

	for (int j = 0; j < len; j++)
	{
		cout << p[j] << endl;
	}
	free(p); //释放p指向的内存
	p=NULL ; //将指针p置为置为空指针,避免误用

	system("pause");
	return 0;
}

输出结果为三个元素的初始值10、20、30,释放p指向的内存后,若再次调用p就会出现内存错误,证明p指向的内存已经被释放。
注意:malloc/free一定要配套使用,以免造成内存泄露

2、new/delete

new对一个变量或自定义类分配内存的用法: A *p=new A;
                         释放内存:delete A;
new对一个数组分配内存的用法:B *p=new B[];
                释放内存:delete[] B;
一起看一下new对数组进行操作的方法:
#include<iostream>
using namespace std;

int main()
{
	int len = 3;
	int* p = new int[3]; //分配3个int元素的内存

	p[0] = 10;
	p[1] = 20;
	p[2] = 30;

	for (int j = 0; j < len; j++)
	{
		cout << p[j] << endl;
	}
	delete[] p; //释放p指向的内存
	P=NULL;  //将指针p置为置为空指针,避免误用
	
	system("pause");
	return 0;
}

输出结果为数组三个元素的初始值10、20、30。
同理,new/delete、new[]/delete[]也要配套使用,避免内存泄露。

五、常见的问题

为啥释放了指针p的内存之后,还要将指针p置为空指针?
答:不管是free函数还是delete运算符,都只是释放了指针p指向的内存,指针p还存在并存放着原有的地址。但是内存被系统回收之后,该地址存放的就是垃圾内容,若p指针也就变成了野指针。若后面程序不小心对指针p进行解引用,可能会造成难以想象的后果,因此在释放内存之后一定要将p置为空指针,以免程序后续发生错误。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值