12、关于动态内存分配

文编写参考狄泰软件学院唐佐林老师的视频课程,如有错误之处,欢迎指正。

一、c++中内存申请与c语言内存申请的异同

1、对于new关键字和malloc函数

new关键字的功能类似于c语言中的malloc,它们都是从堆空间中申请一段内存。下面几点是两者之间的异同点:

  1. new是c++中的关键字,而malloc是c库提供的函数,有些c编译器可能是没有这个库的,那么就会导致不能申请动态空间
  2. new是以具体类型为单位进行内存分配,而malloc是以字节为单位进行内存分配。
  3. new在申请单个类型变量时可以进行初始化,而malloc不可以,calloc函数虽然是将空间里的值初始化为0,但是并不是初始化为用户希望的值,所以还不是真正意义上的初始化。
  4. new能够触发构造函数的调用,malloc仅分配需要的内存空间

在c++中在堆空间为对象申请空间时,是需要调用构造函数的,而这个必须通过new关键字来实现,因为采用malloc函数只是说从堆空间中申请一段内存,但是并不会调用构造函数,也就是说生成的对象是不合法的.

  1. 对象的创建只能使用用new,malloc函数不适合面向对象开发

2、对于delete关键字和free函数

  1. delete在所有c++编译器都被支持
  2. free在没有c库的时候不能够被调用,而某些开发系统中是没有c库的
  3. delete能够触发析构函数的调用,free仅仅归还之前分配的内存空间
  4. 对象的销毁只能够用delete,free不适合面向对象开发
  5. new是通过delete释放空间的,而malloc是以free来释放空间的。对此要特别注意的是:
    (1)对单个类型变量的释放和对数组的释放在形式上是有区别的,对数组空间进行释放时一定要加上[]。
    (2)用new就一定用delete,用malloc就用free,不能够混合使用,原因如下:

因为这样虽然可以通过编译,但是这是会带来问题的,假设用new为对象在对空间中申请了一段内存,那么此时就会出发构造函数的调用,从而完成对象的构造,当使用delete关键字来归还空间时,首先会调用析构函数,进行对象的销毁,然后再归还空间,但是当使用free函数来归还空间,这时是不会自动调用析构函数的,它完成的工作仅仅是归还堆空间,那么如果此时对象里面的成员变量也是从堆空间里面申请的,那么这时就会造成内存泄露。同样地,我们不能够用delete用mallocd申请的堆空间,有可能通过编译,但是同样的也会带来问题,有可能这个问题会暂时没出现,因为用malloc函数申请堆空间时并没有生成一个合法的对象,而用delete关键字就会调用析构函数,去调用一个不合法对象的析构函数是很可能会出现问题的。

二、例程理解

例程1:

#include<iostream>
using namespace std;
int main()
{
	int* p1=new int(5);
	char* p2=new char('a');
	float* p4=new float(2.1f);
	cout<<"*p1="<<*p1<<endl;
	cout<<"*p2="<<*p2<<endl;
	cout<<"*p4="<<*p4<<endl;

	delete p1;
	delete p2;
	delete p4;	
	int* p3=new int[10];
	for(int i=0;i<10;i++)
	{
		p3[i]=i+1;
		cout<<"p3"<<"["<<i<<"]="<<p3[i]<<endl;
	}
	delete[] p3; 
	return 0;
}

在这里插入图片描述
例程2:

#include <iostream>
#include <string>
#include <cstdlib>//C标准通用实用库,此标头定义了几个通用功能,包括动态内存管理,随机数生成,与环境的通信,整数算术,搜索,排序和转换。

using namespace std;

class Test
{
    int* mp;
public:
    Test()
    {
        cout << "Test::Test()" << endl;
        mp = new int(100);
        cout << *mp << endl;
    }
    ~Test()
    {
        delete mp;//归还内存空间

        cout << "~Test::Test()" << endl;
    }
};

int main()
{
    Test* pn = new Test;//用c++的方式,申请空间的同时会调用构造函数,完成对象的构造
    Test* pm = (Test*)malloc(sizeof(Test));//用c语言的方式,只负责申请空间,不负责对象的构造,因此生成的对象不合法
    
    delete pn;//会先调用析构函数销毁对象,然后归还空间
    free(pm);//只负责归还空间,而不负责销毁对象
    
    return 0;
}

在这里插入图片描述
分析:此处只调用了一个构造函数和析构函数,因此证明了此文开头的一些结论,这里也可修改程序验证其余的结论,这里就不一一演示了。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值