new和delete详解
2017-08-29 09:21
615 查看
16、new和delete详解
a.new和delete运算符是用于动态分配和撤销内存的运算符。
对于计算机程序设计而言,变量和对象在内存中的分配都是编译器在编译程序时安排好的,这带来极大的不便,如数组必须大开小用,指针必须指向一个已经存在的变量和对象。对于不能确定需要占用多少内存的情况,动态内存是首要方法
b.new用法
1.开辟单变量地址空间
(使用new运算符必须已知数据类型,new运算符会向系统堆区申请足够的存储空间,如果申请成功,就返回该内存块的首地址,如果申请不成功,则返回0(这里末文有详解,如何判断返回值))
new运算符返回的是一个指向所分配类型变量(对象)的指针。对所创建的变量或对象,都是通过该指针来间接操作的,而动态的对象本身没有标识符名。
一般使用格式:
格式一:指针变量名 = new 类型标识符;
格式二:指针变量名 = new 类型标识符(初始值);
格式三:指针变量名 = new 类型标识符[内存单元个数]
说明:格式1和2都是申请分配某一数据类型所占字节数的内存空间;但是格式二在分配成功后,同时将一初始值放到该内存单元中;格式三可同时分配若干个内存单元,相当于形成一个动态数组。列如:
(1)new int;开辟一个存放整数的存储空间,返回一个指向该内存空间的地址,int a = new int 即为:将一个int类型的地址赋值给整型指针a.
(2)int* a = new int(5)作用同上,但是同时将整数空间赋值为5(*******和格式三不一样********)
2.开辟数组空间
对于数组进行动态分配的格式为:
指针变量名 = new 类型名[下标表达式];
delete[]指向该数组的指针变量名
两式中的方括号必须配对使用,如果delete语句中少了方括号,编译器会认为该指针是指向数组第一个元素的指针,会产生回收不彻底的问题(只回收了第一个元素所占空间),加了方括号后就转化为指向数组的指针,回收整个数组。方括号内部不需要填写元素数,自动补全。
c.delete用法
1.删除单变量地址空间
int * a = new int;
delete a; //释放单个int的空间
2.删除数组空间
int * a = new int[4];
delete []a; //释放int数组空间
d.new和delete使用注意事项
1.new和delete都是内建的操作符,无法重新定制。
2.指针删除和堆空间释放,删除一个指针P(delete p);实际意思是删除了平指向的目标,释放了它所占的堆空间,而不是删除P本身(指针p本省并没有撤销,它自己仍然存在,该指针所占内存空间并未释放),只是释放堆空间后,p成为了空指针。
3. 内存泄漏(memory leak)和重复释放。new与delete 是配对使用的, delete只能释放堆空间。如果new返回的指针值丢失,则所分配的堆空间无法回收,称内存泄漏,同一空间重复释放也是危险的,因为该空间可能已另分配,所以必须妥善保存new返回的指针,以保证不发生内存泄漏,也必须保证不会重复释放堆内存空间。
4. 动态分配的变量或对象的生命期。我们也称堆空间为自由空间(free store),但必须记住释放该对象所占堆空间,并只能释放一次,在函数内建立,而在函数外释放,往往会出错。
5. 要访问new所开辟的结构体空间,无法直接通过变量名进行,只能通过赋值的指针进行访问。
用new和delete可以动态开辟和撤销地址空间。在编程序时,若用完一个变量(一般是暂时存储的数据),下次需要再用,但却又想省去重新初始化的功夫,可以在每次开始使用时开辟一个空间,在用完后撤销它
(摘自Internet)
C++中的new操作符在分配内存失败时默认的操作是抛出一个内置的异常,而并不是直接返回空指针;这样的话,再把返回值与空指针比较,就没有什么意义了;因为,C++抛出异常之后,就直接跳出new操作符所在的那一行代码,而不再执行后续的代码行了,所以,对new操作符返回值的判断代码就执行不到了;当然,标准C++也提供了抑制抛出异常的方法,使之不再排除内存分配失败的异常,转而直接返回空指针,这是因为比较古老的编译器里面可能没有异常处理机制,不能捕获到异常;如:
int* p = new int[SIZE];
if(p == 0) //检查p是否是空指针;这个判断没有意义;
{
return -1;
}
所以,在C++中有两种方法来处理new操作符分配内存失败的错误;
1、通过捕获new操作符抛出的异常:
char* p = NULL;
try
{
p = new char[1024];
}
catch(const std::bad_alloc& ex)
{
//exception handle;
return -1;
}
2、抑制异常的抛出:
char* p = NULL;
p = new(std::nothrow)char[1024]; //这样的话,如果new分配内存失败,就不会再抛出异常,而是返回空指针了;
if(p == NULL) //这样的判断就有意义了;
{
//error handle;
return -1;
}
a.new和delete运算符是用于动态分配和撤销内存的运算符。
对于计算机程序设计而言,变量和对象在内存中的分配都是编译器在编译程序时安排好的,这带来极大的不便,如数组必须大开小用,指针必须指向一个已经存在的变量和对象。对于不能确定需要占用多少内存的情况,动态内存是首要方法
b.new用法
1.开辟单变量地址空间
(使用new运算符必须已知数据类型,new运算符会向系统堆区申请足够的存储空间,如果申请成功,就返回该内存块的首地址,如果申请不成功,则返回0(这里末文有详解,如何判断返回值))
new运算符返回的是一个指向所分配类型变量(对象)的指针。对所创建的变量或对象,都是通过该指针来间接操作的,而动态的对象本身没有标识符名。
一般使用格式:
格式一:指针变量名 = new 类型标识符;
格式二:指针变量名 = new 类型标识符(初始值);
格式三:指针变量名 = new 类型标识符[内存单元个数]
说明:格式1和2都是申请分配某一数据类型所占字节数的内存空间;但是格式二在分配成功后,同时将一初始值放到该内存单元中;格式三可同时分配若干个内存单元,相当于形成一个动态数组。列如:
(1)new int;开辟一个存放整数的存储空间,返回一个指向该内存空间的地址,int a = new int 即为:将一个int类型的地址赋值给整型指针a.
(2)int* a = new int(5)作用同上,但是同时将整数空间赋值为5(*******和格式三不一样********)
2.开辟数组空间
对于数组进行动态分配的格式为:
指针变量名 = new 类型名[下标表达式];
delete[]指向该数组的指针变量名
两式中的方括号必须配对使用,如果delete语句中少了方括号,编译器会认为该指针是指向数组第一个元素的指针,会产生回收不彻底的问题(只回收了第一个元素所占空间),加了方括号后就转化为指向数组的指针,回收整个数组。方括号内部不需要填写元素数,自动补全。
c.delete用法
1.删除单变量地址空间
int * a = new int;
delete a; //释放单个int的空间
2.删除数组空间
int * a = new int[4];
delete []a; //释放int数组空间
d.new和delete使用注意事项
1.new和delete都是内建的操作符,无法重新定制。
2.指针删除和堆空间释放,删除一个指针P(delete p);实际意思是删除了平指向的目标,释放了它所占的堆空间,而不是删除P本身(指针p本省并没有撤销,它自己仍然存在,该指针所占内存空间并未释放),只是释放堆空间后,p成为了空指针。
3. 内存泄漏(memory leak)和重复释放。new与delete 是配对使用的, delete只能释放堆空间。如果new返回的指针值丢失,则所分配的堆空间无法回收,称内存泄漏,同一空间重复释放也是危险的,因为该空间可能已另分配,所以必须妥善保存new返回的指针,以保证不发生内存泄漏,也必须保证不会重复释放堆内存空间。
4. 动态分配的变量或对象的生命期。我们也称堆空间为自由空间(free store),但必须记住释放该对象所占堆空间,并只能释放一次,在函数内建立,而在函数外释放,往往会出错。
5. 要访问new所开辟的结构体空间,无法直接通过变量名进行,只能通过赋值的指针进行访问。
用new和delete可以动态开辟和撤销地址空间。在编程序时,若用完一个变量(一般是暂时存储的数据),下次需要再用,但却又想省去重新初始化的功夫,可以在每次开始使用时开辟一个空间,在用完后撤销它
(摘自Internet)
C++中的new操作符在分配内存失败时默认的操作是抛出一个内置的异常,而并不是直接返回空指针;这样的话,再把返回值与空指针比较,就没有什么意义了;因为,C++抛出异常之后,就直接跳出new操作符所在的那一行代码,而不再执行后续的代码行了,所以,对new操作符返回值的判断代码就执行不到了;当然,标准C++也提供了抑制抛出异常的方法,使之不再排除内存分配失败的异常,转而直接返回空指针,这是因为比较古老的编译器里面可能没有异常处理机制,不能捕获到异常;如:
int* p = new int[SIZE];
if(p == 0) //检查p是否是空指针;这个判断没有意义;
{
return -1;
}
所以,在C++中有两种方法来处理new操作符分配内存失败的错误;
1、通过捕获new操作符抛出的异常:
char* p = NULL;
try
{
p = new char[1024];
}
catch(const std::bad_alloc& ex)
{
//exception handle;
return -1;
}
2、抑制异常的抛出:
char* p = NULL;
p = new(std::nothrow)char[1024]; //这样的话,如果new分配内存失败,就不会再抛出异常,而是返回空指针了;
if(p == NULL) //这样的判断就有意义了;
{
//error handle;
return -1;
}
相关文章推荐
- C++ 内存分配操作符new和delete详解
- 关于[]静态数组和new分配的动态数组的区别
- newinstance()和new有什么区别?
- C++里 数组new 和delete问题
- malloc/free与new/delete的区别
- new delete malloc free
- Codeforces 500A:New Year Transportation(水题)
- C++ placement new
- rest, reset, ready for a new generation.
- PowerShell小技巧之使用New-Module命令动态创建对象
- spring注入的对象和new的对象到底有啥区别
- new创建对象数组 比较 new单个对象的优点
- new/delete 和malloc/free 的区别和联系
- new和malloc的区别
- The New Year: Meeting Friends Codeforces Round#375-A
- How to create a new process
- Google Round B China New Grad Test 2014
- 虚拟内存(VirtualAlloc),堆(HeapAlloc/malloc/new)和Memory Mapped File
- G++, new types may not be defined in a return type
- 关于动态贴图问题不能动态通过texture改变只能重新new 新material