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.