E1:
E2:
两个程序都可以编译,但第二个运行会出现段错误。两个程序的区别在,第二个程序的 str 属于已
初始化变量,str 如果是局部变量则指向栈上的内存区域,如果是 static 或全局变量则指向进程的
data 段内存区域。
data 段权限是
可读、
可写;第一个程序中 "hello, world" 是一个字符串面量,str 的确指向其地址,但该地址存在于在进程的
text 段,
text 段除了保存常量还保存
可执行代码,因此是不允许
可写权限的,而是只允许
可读、
可执行权限。
char str[] = "hello, world"; str[1] = 'a';
E2:
char *str = "hello, world"; str[1] = 'a';
char p[] = "hello"; //1 char *p = "hello"; //2 char *p; p = (char *)malloc(sizeof(char)*6);strcpy(p, "hello"); //3
1中所有6个char字符都连续的存放在栈区。
2中的"Hello"存在程序内存的常量区中,是编译时就固定下来的(不可更改),然后p是一个指向常量区"hello"的指针,p本身存在栈区。
3中malloc向堆申请了空间,p存放在栈区,指向malloc申请出来的地址,最后"hello"就被copy到了p所指向的地址。
从速度来看1中栈的数据都是直接读的,另外两种都需要通过指针间接读取,所以1显然是最快的。
我觉得首先如果字符串很小且确定,可以用1的写法,在栈区速度快。
如果字符串很大或者不确定,要知道栈区大小是有限的,所以采用3的动态分配比较好。
如果字符串被大量复用,其实可以采用2中写法,这样只要引用了常量区的同一字符串,他们将会共用同一块地址。(当然这种共用是合理的,因为那里的字符串是不可修改的,且到程序结束才会被释放)。