关于C语言中char*a[]空间分配问题的一旦感悟

大学时候没好好学,导致实际用诸如char *a[]的时候,畏畏缩缩的,含泪花了1整体系统地复习了一下,记录一下学习心得。

问题1:如果定义了一个字符指针char *a,问系统到底因为这句话,分配了多大的空间?

对于涉及不到底层的同学,可能一辈子都不会考虑这个问题,而堆或者栈,一旦硬件大小确定了,它的空间就定死了,你每定义一个变量,这块空间就要划出相应的大小,甚至略大于这个大小(地址对齐),用来分配给你定义的变量。有时候我就比较好奇,系统到底分配了多大给我定义的变量。

以前没学好,一直以为分配了char的大小,就一个byte的大小,结果现在知道了,对于指针来说,指针分配空间是一个int的空间大小,即sizeof(int),不同环境下这个值是不一样的,我这里就默认int是32位,即4个bytes了。而带来的问题是,我用char定义了一个指针,分配的是32位地址,那我这个char又是干什么用的?我的理解是,可以想象成偏移地址,即需要连续读取的长度。举例说明一下:

如上图,如果a = 0x01,那么*a = 2,相当于寻址时,a代表了我要寻找的起始地址,而char决定了我的从这个起始地址开始要寻找的长度,由于char占用1个byte,即len为1,于是得到结果*a = 2。类比一下,如果我定义的是int *a,然后a = 0x01,那么*a会是多少了?再来类比分析一下,a=0x01,那么起始地址是0x01,那么我要连续读多少位呢?一个int的大小,即32位,4个bytes,那么0x01~0x04这4位都将被寻址到。对于小端设备,*a = 0x05040302。

 所以说,对于char *a问题,其实系统给你分配的地址大小为一个指针的大小,而前面的char只是用来寻址的偏移量,跟系统分配空间没有关系

问题2:char *a = "i love currant",这期间系统分配了多大空间?

虽然这只有一句话,但是系统却做了3件事情:

1.首先在常量区,释放了14个bytes的空间,用来存"i love currant",并且为了区分中止,自动在结尾释放了一个1byte放‘\0’,所以常量区就消耗了至少15个btyes;

2.定义了一个指针a,释放了一个指针的大小,即4个bytes;

3.将a 等于 "i love currant"这句话的首地址,即a指向这句话的首地址。

由问题2引申3个问题:

问题2.1:如果char b = a[2],b等于多少?

a指向"i love currant"的首地址,即i的地址,偏移2位,所以b = ‘l’;

问题2.2:可以a[2] = 'p'吗?

不可以,指针a指向的是常量区,常量区的内容只读,不写。

问题2.3:怎么才能实现a[2] = 'p'?

从定义初下手,定义char a[] = "i love currant",那么a[2] = 'p'合法,操作以后字符串变成了"i pove currant"

再由问题2.3引申问题3:

问题3:char *a = "i love currant"和char a[] = "i love currant",sizeof(a),结果一样吗?

不一样。这两个申请空间的过程完全不同。

char *a = "i love currant",仅对a来说,系统只给a分配了一个指针大小的空间,即4个bytes,而存"i love currant"的地方在常量区,虽然sizeof(a)=4,但其实总系统消耗量可不止4。

char a[] = "i love currant",这其实是数组的一种初始化方式,系统不知道这个数组要分配空间到底多大,于是先计算放"i love currant"需要多大,总共14个字符,所以是14bytes,但是别忘了,字符需要一个'\0'在内存里跟别人隔开,中止区分,所以先算出存"i love currant"需要15个bytes,于是给数组a开辟了15个bytes的空间大小,然后将"i love currant"+'\0'放到开辟的空间里。所以这里的sizeof(a) = 15。你以为这就完了?不,a既是变量名,也是首地址,所以还是需要留一个指针的大小,存让a本身存下字符串首指针。

以上就是我自我学习的理解,不一定全对,有问题还请相互指教。

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值