何时用new?

本文探讨了C语言中数组的使用方式,包括静态数组与动态数组的区别,并介绍了new关键字的应用场景及其注意事项。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

注:本文仅自己的拙见,有错误的话,希望大家不吝赐教。

  1. 申请对象空间不确定时,用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[]
  1. 需要空间较大时,用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,则很容易出现继续使用已释放空间的问题。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值