C++动态内存——new和delete运算符

new和delete运算符

new运算符和malloc函数

new运算符能够为我们提供灵活的动态内存分配空间,使用new来申请动态内存空间同时也要注意,区别于普通的变量声明,它需要手动释放内存,普通的变量定义比如int a,cahr b[]定义之后系统会动的为其分配内存空间,并在离开作用域之后自动释放内存空间,而new运算符申请声明的变量如new int a的内存是不会被自动释放的,所以需要程序员手动释放

我们可以通过alloc函数或者用new运算符来申请内存空间,它们会申请特定的内存空间并返回一个地址,所以需要用指针变量来接受它

可以写一个测试用例

int main(){
 while(1){
     int a = 3;
 }
 return 0;
}

查看任务管理器内存占用情况

在这里插入图片描述

int main(){
 while(1){
     int *a = new int(3);
 }
 return 0;
}

在这里插入图片描述

可见用new运算符申请的a的内存完全没有释放占据了将近一倍的内存空间,所以对于用new运算符申请的内存,必须通过程序员手动释放

new运算符的用法

int *p1 = new int; //*p1为一个随机的值
int *p2 = new int(3); 
float *f1 = new float; //默认值的指针
float *f2 = new float(23.35); //带有初始化的指针 
int *a1 = new int[10]; //申请一个数组指针,a1指向数组的最开始位置
int *a2 = new int[4]{1,2,3,4}; //生成一个具有初始化值的数组指针,a2指向数组的最开始位置

//通过malloc函数申请空间,并不会为*a进行赋值,是一个随机值,输出它会显示一个随机值
int *a = (int*)malloc(sizeof(int));

使用常规情况申请和使用new运算符申请的区别比如对于常规的数组,我有搜到资料

There is a difference between declaring a normal array and allocating a block of memory using new. The most important difference is, normal arrays are deallocated by compiler(普通数组的内存是由编译器申请的) (If array is local, then deallocated when function returns or completes(在离开作用域或者函数返回之后它就会被自动释放)). However, dynamically allocated arrays always remain there until either they are deallocated by programmer or program terminates.(而通过new运算符定义的数组类型智能通过程序员手动释放空间或者整个程序结束)

new and delete operators in C++ for dynamic memory - GeeksforGeeks

通过nothrow来避免内存不够造成的new运算符申请动态内存出现的异常

int *p = new(nothrow) int(4);
if(!p){
    cout<<"There are lack of memory,please check the program and the memory of the computer!\n";
}

在new运算符后面加一个nothow,如果申请内存空间时空间不够,指针会返回一个nullptr

If enough memory is not available in the heap to allocate, the new request indicates failure by throwing an exception of type std::bad_alloc, unless “nothrow” is used with the new operator, in which case it returns a NULL pointer(在堆内存空间不是很足够的情况下,通过new运算符申请内存空间会抛出std::bad_alloc异常,而用nothrow修饰new运算符会在出现这种情况时返回一个空指针nullptr) (scroll to section “Exception handling of new operator” in this article). Therefore, it may be good idea to check for the pointer variable produced by new before using it program.(在使用new运算符之前检查它是否正常生成是一个很好的习惯)

delete运算符和free函数

前面讲到了通过new运算符和malloc来申请为创建的变量申请内存空间,对于这写申请的内存空间,可以通过delete运算符free函数来释放存储空间,但是这里需要明确delete运算符到底释放的是什么?通过代码可以很好的理解delete运算符释放的到底是什么

int main(){
    int *p = new int(3);
    cout<<"The value of the point is:"<<*p<<endl;
    cout<<"The point is in:"<<p<<endl;
    delete p;
    cout<<"The value of the point is:"<<*p<<endl;
    cout<<"The point is in:"<<p<<endl;
    return 0;
}

在这里插入图片描述

从测试结果可以看到,delete运算符只是删除了指针指向的值,并没有删除指针变量本身,如果需要回收指针变量的话,可以用p = nullptr来回收指针变量的内存,free也是如此

int *a = new int(3);
delete a; //释放指针的内存空间
a = nullptr; //释放指针变量的内存空间

//释放数组的内存空间
int *a1 = new int[3]{1,3,4};
delete[] a1;

//通过free来释放空间
int *a2 = new int(3);
free(a2);

delete运算符和free以及new和malloc的区别

free是一个函数delete是一个运算符,free函数是从c语言中继承过来的,c语言中是没有面向对象的概念的,所以通过free函数来释放指针的空间是不会调用对象的析构函数的,而通过delete运算符来释放的内存空间的话是会调用对象的析构函数的

与此相似的是,new运算符和malloc函数也是同一个原理,new运算符会实例化一个对象,即调用对象的构造器,但是malloc函数不会参与实例化,可以通过一段代码来看

class A{
    int a;
public:
    A(){
        cout<<"I am the constructor\n";
        a = 3;
    }
    void print(){
        cout<<a<<endl;
    }
    ~A(){
        cout<<"I am into the destructor\n";
    }
};
int main(){
    A *a = new A; //实例化一个类A
    a->print(); //打印A的成员变量
    delete a;
    A *b = (A*) malloc(sizeof (A));
    b->print();
    free(b);
    return 0;
}

在这里插入图片描述

Gfg上面的说法

In C++, delete operator should only be used either for the pointers pointing to the memory allocated using new operator or for a NULL pointer, and free() should only be used either for the pointers pointing to the memory allocated using malloc() or for a NULL pointer.

The most important reason why free() should not be used for de-allocating memory allocated using NEW is that, it does not call the destructor of that object while delete operator does.

delete and free() in C++ - GeeksforGeeks

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值