何时用new?
2016-06-24 12:19
232 查看
注:本文仅自己的拙见,有错误的话,希望大家不吝赐教。
申请对象空间不确定时,用new。(避免对只有在运行时才能确定实际大小的对象提前静态确定其大小的话,犯太大导致浪费或太小导致不足无法处理的错误。)
创建静态数组时,是编译时确定数组大小,以便分配内存,如:
注意:C99支持动态数组,C90时GCC编译器扩展也允许数组大小用变量。 即:
可以用const:
const修饰的翻译期标识符具有常量语义,对于编译期(源代码)而言,必须在定义时同时被初始化,且一旦被定义即无法修改,否则产生编译错误。
对于编译器而言,如果用于初始化const对象的值在编译期即能被确定,则可以把这个const对象优化掉,即通过类型检查后用这个值代替这个对象本身(这点效果和宏定义替换类似,但更安全),这被称为编译期const对象。编译期const对象在编译期完全确定,对于运行期而言相当于不存在。由于内嵌至数据段中,只是直接复制到内存,无所谓“初始化”(但是这点行为上和基本类型数据的初始化类似)。
对于无法在编译期确定的运行期常量,一旦通过编译链接,在运行期的初始化行为,和对象本身被创建的时机相同——例如全局/静态对象在进程初始化时被初始化,作为函数参数的const对象(包括任何引用类型)在参数传递生成参数时同时初始化。
注:数组大小最好不要用变量,变长数组可以用vector;也可以用new申请动态数组,但此时要注意new返回数组的指针,而并非数组,所以:
需要空间较大时,用new,就能使用的最大内存大小而言:
堆栈区<全局数据区<堆区<内存映射文件<磁盘<云存储
所以有时为了使用比堆栈区或全局数据区更大的内存,就要使用new占据堆区。
但是,使用new时,要注意使用delete动态释放内存。
注:
int a = 9;
int *p1 = new int();
int *p = p1;
p1 = &a;
delete p;
/*此时,p可以不是new时,直接赋值的指针,但p指向的必须是new的空间。
释放的是p指向的用new申请的空间,释放后,p为悬停指针,可以为其重新赋 值,但是注意不要直接使用悬停指针。*/
这里存在一个问题,如果直接:
此时,不能再用p1和p,因为它们均指向一个已释放的空间。对于p而言,可以释放后,及时为其赋值来避免这个问题;但是对于指向该空间的其他指针如p1,则很容易出现继续使用已释放空间的问题。
申请对象空间不确定时,用new。(避免对只有在运行时才能确定实际大小的对象提前静态确定其大小的话,犯太大导致浪费或太小导致不足无法处理的错误。)
创建静态数组时,是编译时确定数组大小,以便分配内存,如:
int a[20]={0};//运行时初始化 const int a[20]={0};//编译时初始化(这里仅为了说明初始化的时机,一般不这样初始化const)
注意:C99支持动态数组,C90时GCC编译器扩展也允许数组大小用变量。 即:
int a= 7; int b[a];//但是此时不能初始化
可以用const:
const int a = 7; int b[a] = {0};//编译期a会被优化替换成7
const修饰的翻译期标识符具有常量语义,对于编译期(源代码)而言,必须在定义时同时被初始化,且一旦被定义即无法修改,否则产生编译错误。
对于编译器而言,如果用于初始化const对象的值在编译期即能被确定,则可以把这个const对象优化掉,即通过类型检查后用这个值代替这个对象本身(这点效果和宏定义替换类似,但更安全),这被称为编译期const对象。编译期const对象在编译期完全确定,对于运行期而言相当于不存在。由于内嵌至数据段中,只是直接复制到内存,无所谓“初始化”(但是这点行为上和基本类型数据的初始化类似)。
对于无法在编译期确定的运行期常量,一旦通过编译链接,在运行期的初始化行为,和对象本身被创建的时机相同——例如全局/静态对象在进程初始化时被初始化,作为函数参数的const对象(包括任何引用类型)在参数传递生成参数时同时初始化。
注:数组大小最好不要用变量,变长数组可以用vector;也可以用new申请动态数组,但此时要注意new返回数组的指针,而并非数组,所以:
int a[] = new int[9];//error,会提示说不能将int *转化为int[]
需要空间较大时,用new,就能使用的最大内存大小而言:
堆栈区<全局数据区<堆区<内存映射文件<磁盘<云存储
所以有时为了使用比堆栈区或全局数据区更大的内存,就要使用new占据堆区。
但是,使用new时,要注意使用delete动态释放内存。
注:
int a = 9;
int *p1 = new int();
int *p = p1;
p1 = &a;
delete p;
/*此时,p可以不是new时,直接赋值的指针,但p指向的必须是new的空间。
释放的是p指向的用new申请的空间,释放后,p为悬停指针,可以为其重新赋 值,但是注意不要直接使用悬停指针。*/
这里存在一个问题,如果直接:
int *p1 = new int(); int *p = p1; delete p;
此时,不能再用p1和p,因为它们均指向一个已释放的空间。对于p而言,可以释放后,及时为其赋值来避免这个问题;但是对于指向该空间的其他指针如p1,则很容易出现继续使用已释放空间的问题。
相关文章推荐
- IE7降低内存和降低CPU的几个技巧
- 如何高效的使用内存
- DOS下内存的配置
- XP/win2003下发现1G的内存比512M还慢的解决方法
- PowerShell实现动态获取当前脚本运行时消耗的内存
- C#实现把dgv里的数据完整的复制到一张内存表的方法
- SQL语句实现查询SQL Server内存使用状况
- C语言内存对齐实例详解
- 深入学习C语言中memset()函数的用法
- 全局变量与局部变量在内存中的区别详细解析
- VB读取线程、句柄及写入内存的API代码实例
- php运行提示:Fatal error Allowed memory size内存不足的解决方法
- IE浏览器IFrame对象内存不释放问题解决方法
- C#之CLR内存深入分析
- JavaScript 变量、作用域及内存
- JavaScript避免内存泄露及内存管理技巧
- J2ME编程中的几个重要概念介绍
- c++实现逐行读取配置文件写入内存的示例
- Shell脚本查看进程内存真实占用情况
- w3wp.exe占用cpu过高的解决方法第1/2页