关于char *和char []的个人理解

本文讲述了作者在编程过程中遇到的段错误问题,通过分析发现是因为混淆了char*和char[]的使用场景。文章详细解释了这两种数据类型在内存中的不同存储方式,并介绍了Linux进程的地址空间划分。

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

今天白天练习一些编程题遇到了一个问题,是代码写好后总是莫名出现段错误,再三检查语法和算法,百思不得其解。
之后突然想到,可能是把char *和char[]搞混了。

原本应该是 char a[] = “hello”;
写成了char * a = “hello”;

在这之前我一直以为两者没有区别,然后仔细的思考了一番,发现了问题的所在。

一个linux进程分为几个部分(从一个进程的地址空间的低地址向高地址增长):
1.text段,就是存放代码,可读可执行不可写,也称为正文段,代码段。
2.data段,存放已初始化的全局变量和已初始化的static变量(不管是局部static变量还是全局static变量)
3.bss段,存放全局未初始化变量和未初始化的static变量(也是不区分局部还是全局static变量)
以上这3部分是确定的,也就是不同的程序,以上3部分的大小都各不相同,因程序而异,若未初始化的全局变量定义的多了,那么bss区就大点,反之则小点。
4.heap,也就是堆
5.stack,栈
6.再往上,也就是一个进程地址空间的顶部,存放了命令行参数和环境变量。

char * a = “hello” 初始化后,内容“hello”存放在存放在data段,在这个区域是代码编译后写在汇编里的不能改变,而指针变量的地址a存放在栈区,a是可以改变的。所以每次当试图对data区的内容进行操作是会报出段错误。

而char a[] = “hello”;初始化时,所有的数据都是在栈区初始化,内容是可变的。

以下为转自网络:

第一,如果是全局的和静态的
char *p = “hello”;
这是定义了一个指针,指向rodata section里面的“hello”,可以被编译器放到字符串池。在汇编里面的关键字为.ltorg。意思就是在字符串池里的字符串是可以共享的,这也是编译器优化的一个措施。
char a[] = “hello”;
这是定义了一个数组,分配在可写数据块,不会被放到字符串池。

第二,如果是局部的
char *p = “hello”;
这是定义了一个指针,指向rodata section里面的“hello”,可以被编译器放到字符串池。在汇编里面的关键字为.ltorg。意思就是在字符串池里的字符串是可以共享的,这也是编译器优化的一个措施。另外,在函数中可以返回它的地址,也就是说,指针是局部变量,但是它指向的内容是全局的。
char a[] = “hello”;
这是定义了一个数组,分配在堆栈上,初始化由编译器进行。(短的时候直接用指令填充,长的时候就从全局字符串表拷贝),不会被放到字符串池(同样如前,可能会从字符串池中拷贝过来)。注意不应该返回它的地址。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值