看看下面的C代码.
char * str1 = "hello";
它创建一个分配给只读内存的char数组,str1指定为第一个元素的指针.由于只读,如果没有分段错误,则无法更改内存.在这个声明中:
int * p = 1;
p现在被分配为1,实际上可以重新分配给不同的值而不会发生分段错误.为什么是这样?是否只是编译器决定只在字符串文字的情况下读取内存?
似乎有很多你误解的事情.
首先在这里:
char * str1 = "hello";
Run Code Online (Sandbox Code Playgroud)
没有人限制你去做
str1 = "hello again";
Run Code Online (Sandbox Code Playgroud)
在以后.它仍然是正确的.但是,你不能做的是:
str1[0] = 'a'; // This you can't do- because you aren't allowed to modify string literal
Run Code Online (Sandbox Code Playgroud)
所以这意味着你不应该改变字符串文字,但你可以使指针指向另一个对象.
用整数示例:
int * p = 1;
Run Code Online (Sandbox Code Playgroud)
上面的行不好,因为p现在指向内存地址1并且取消引用它是一个坏主意.
在功能上,char或者int指针的行为大致相同,只是你无法修改字符串文字,这是唯一的限制.
如果是两者char和int指针,您可以重新分配指针.
并且(除了char指针指向字符串文字的情况),您还可以更改它们指向的对象的内容.例如
int x = 1;
int *y = &x;
*y = 19; // Fine, now x has value 19
char a = 'b';
char *c = &a;
*c = 'r'; // Fine, now a has value 'r'
Run Code Online (Sandbox Code Playgroud)
综上所述,我会说这样的:char和int指针和一般的"循规蹈矩"以同样的方式所有指针:您可以分配给它们的地址,改变它们指向的对象(授予它们指向有效的内存),以防万一字符串常量,如果char指针正好指向一个字符串字面你不能改变的 对象,以该char指针指向.
int * p = 1;
p现在分配为1.
错误.p现在指向内存地址1.
这可能会导致各种问题,从您没有正确分配从该地址开始的任何内存块开始.
更糟糕的是,即使你已经设法在地址1处分配了一个内存块,因为这个地址没有对齐int(即1不能被整除sizeof int),你的代码很容易出现未对齐的加载/存储操作.
如果您的平台(即指定的编译器+底层硬件架构)不支持这些操作,则任何读取或写入的尝试p都可能导致:
前者比后者好,因为有了总线故障,至少你会立即意识到这个问题,而对于一个未确定的结果,某些意外的行为可能会在你的程序执行期间的某个后期出现,让你进入调试会议之神的怜悯.