关闭

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

101人阅读 评论(0) 收藏 举报
分类:

今天白天练习一些编程题遇到了一个问题,是代码写好后总是莫名出现段错误,再三检查语法和算法,百思不得其解。
之后突然想到,可能是把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”;
这是定义了一个数组,分配在堆栈上,初始化由编译器进行。(短的时候直接用指令填充,长的时候就从全局字符串表拷贝),不会被放到字符串池(同样如前,可能会从字符串池中拷贝过来)。注意不应该返回它的地址。

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场