C语言新手求教:为何能读取分配指针的字符却无法写入?
兄弟,我来给你掰扯清楚这个问题——你遇到的段错误核心原因就是字符串字面量确实存放在只读内存里,咱们一步步拆解:
核心原因:字符串字面量位于只读内存
当你写出类似char *str = "YourString";这样的代码时,"YourString"这个字符串字面量是在编译阶段就被打包进程序的只读数据段(通常叫.rodata)里的。操作系统会标记这块内存为只读,防止程序意外修改它——所以你尝试用*(str+1) = 'x'这种方式去写这块内存,直接就触发Segmentation fault了,完全符合预期。
为什么“修改指针本身”没问题?
你提到之前修改整个指针不会报错,这是因为指针变量本身是存在栈内存里的(可写)。比如你写str = "AnotherString";,这只是改变了str这个指针变量里存储的地址值,让它指向了另一个字符串字面量(同样在只读区),并没有修改任何只读内存里的内容,所以当然不会出错。
关于
*(str+1)的本质 *(str+1)和str[1]是完全等价的写法——C语言里数组下标访问本质就是指针偏移。str是指向第一个字符的指针,str+1就是偏移一个char长度后的内存地址,*(str+1)就是取这个地址上的值。如果这个地址属于只读内存,写操作就会触发段错误;如果是可写内存(比如栈上的字符数组),写操作就正常。
解决办法:用字符数组代替指针指向字面量
如果你需要修改字符串内容,别用char *str = "Hello";,改成字符数组:
char str[] = "Hello";
这样字符串会被复制到栈内存里,属于可写区域,你再用str[1] = 'a'或者*(str+1) = 'a'就完全没问题了。
内容的提问来源于stack exchange,提问作者anon
相关产品推荐
相关产品推荐

