new和delete

new&delete

****c语言中使用malloc,realloc,calloc关键字来开辟动态空间

c++兼容c语言,对于内置类型尤其是自定义类型的动态申请简化用法,功能一致

calloc可以设置初始值,但繁琐

格式new加类型返回指针

自动计算大小,不需要强转

new开辟空间调用构造函数初始化(多个数据,多次调用构造函数)

delete释放空间调用析构函数(多个数据,多次调用析构函数)

int main()
{
    //功能一致,用法简化
    int *ptr1=(int *)malloc(sizeof(int));
    int *ptr2=new int;
    
    int *ptr3(int *)malloc(sizeof(int)*10);
    int * ptr4=new int[10];
    
    //销毁
    free(ptr1);
    free(ptr3);
    //指针是内置类型不会自动调用析构函数
    delete ptr3;
    delete[] ptr4;
    
    //new额外支持开空间和初始化
    //初始化
    int* ptr5=new int(10);
	//多个对象
    int* ptr6=new int[10];
    //数组
    int* ptr7=new int[10]{1,2,3,4,5};
    int* ptr8=new int[10]{};
    //错误
    int* ptr9w int [10]=1,2,3,4,5};
    
    return 0;
}

相对于内置类型new和malloc没什么区别,new最重要的是针对自定义类型,c语言中malloc对于开辟空间基本上没办法使用,无法调用构造函数

new[]&delete[]

调用多次构造和多次析构

class A
{
    
    public:
    	  	A(int a)
                :_a(a)
                {}
    private:
    	int _a;
};
int main()
{
    A A1(1);
    A A1(2);
    			//有名对象
    A* ptr1=[5]{A1,A2};
    delete[] ptr1;
    			//匿名
    A* ptr2=[5]{A(1),A(2)};
    delete[] ptr2;
    //隐式类型转换
    A* ptr3=[5]{1,2};
    delete[] ptr3;
    return 0;
}

不匹配

不匹配未定义行为报错

class A
{
    public:
    	A(int a)
            :_a(a)
        	{}
        ~A()
        {
            ;
        }
    private:
    	int _a;
};
int main()
{
    A* a1=new A;
    delete a1;
    A* a2=new A[10];
    delete[] a2;
    A* a3=new A[10];
    delete a3;
    //a3的不匹配行为不会造成,内存泄漏
    //但是如果显示定义析构,申请空间会在前面多申请存储个数值
    //指针会指向错误
    //没有调用析构是不会报错
    return 0;
}

一定要匹配使用

class A
{
    public:
    	A(int a)
            :_a(a)
        	{}
        ~A()
        {
            ;
        }
    private:
    	int _a;
};
int main()
{
    int * p=new int[10];
    //在存在delete[]时
    //实际上开辟sizeof(int)*10+4,这四字节负责记录个数,而指针p指向这四字节后的第一个地址
    //当它释放空间时,调用析构根据前四字节的数据调用n次析构函数
    //调用operator delete,会将指针向前偏移,然后释放整个空间
    delete[] p;
   	A* p1=new A[10];
       //自定义类型A,没有显示定义析构函数,而编译器生成的默认析构函数因为没资源清理,就没有调用,直接返回首地址的位置
    delete p1;
 
    return 0;
}

operator new函数&operator delete函数

这两个是库函数不是重载

new是由operator new函数来开辟空间

delete是由operator delete函数来释放空间

operator newoperator delete对malloc与free的封装

int main()
{
    Stack* pst1=(Stack*)operator new(sizeof(Stack));
    Stack* pst2=new Stack;
    return 0;
}
new T[n];
//调用operator new[]函数,在operator new[]调用operator new完成对N个对象空间的申请
//在申请的空间上执行n次构造函数
delete[];
//在释放的对象空间上执行n次析构函数,完成n个对象中资源的清理
//调用operator delete[]释放空间,实际在operator delete[]中调用operator delete来释放空间	
    

定位new

定位new表达式(placement-new)替换new

定位new通常是配合内存池来使用的

**STL自建内存池(池化技术)**将某些重复使用的资源放在内存池,相对于在堆中调用更快,(内存还是从堆里分配的)

格式new(指针)类型(参数列表)

int main()
{
    //和malloc使用方法一样
    Stack* pst=(Stack*)operator new(sizof(Stack));
    pst->pst(5);//无法显示调用构造
    new(pst)Srack(5);//显示调用构造函数
	return 0;
}

异常

抛异常,一般情况下申请空间不会出现异常,但当申请空间过大时就会出现问题

new申请失败抛异常,出现抛异常后就需要捕获异常

只有在try,catch内才会捕获异常

int main()
{
    //捕获异常
    try
    {
        char* p1=new char[1000000000];
        //cout将p1当做字符串打印,但是指针没有/0
        //所以可以将p1强制类型转换
        cout<<(void*)p1<<endl;
	}
    //执行流跳跃出现异常会直接跳转到catch函数,无视后面语句
    //异常会被exception类型获取
    catch(cosnt exception& e)
    {
        //可以通过what获知错误信息
        cout<<e.what()<<endl;
    }
    return 0;
}

malloc/free&new/delete的区别

malloc和free是函数,new和delete是操作符

malloc申请的空间不能初始化,new可以初始化

malloc使用繁琐,new简化

malloc返回void*,new返回空间的类型

malloc申请失败返回空,需要判空,new申请失败抛异常,需要捕获异常

申请自定义类型对象时,malloc,free只会开辟空间不会调用构造函数与析构函数,而new申请空间会调用构造函数完成对象的初始化,delete在释放空间前会调用析构函数完成空间中资源的清理

内存泄漏

没有释放内存就是内存泄漏

普通内存泄露不会有什么危害,系统会自己回收

但是对于长期运行的程序却有很大的危害

内存分布

堆 自由申请空间

栈 函数调用建立栈帧,存储局部变量

静态区(数据段)

常量区(代码段)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值