C语言中为什么无法修改字符串指针指向的单个字符?
段错误触发原因分析
你给出的代码触发段错误的核心原因是非法修改了只读内存区域的内容,具体原理如下:
- C语言里用双引号直接定义的字符串属于字符串字面量,编译器编译时会把这类字面量统一存入进程的只读数据段(.rodata段),操作系统会对该内存段设置只读权限,运行时不允许任何修改操作。
- 代码中
char* someString = "original string";只是声明了一个字符指针,指向存放在只读数据段的这个字符串的首地址,没有把字符串内容拷贝到可写的内存区域。 - 第二行
someString[1] = 'O';试图对只读内存区域执行写入操作,操作系统捕获到非法内存访问行为后,就会抛出段错误终止程序运行。
修复方案
如果需要修改字符串内容,需要把字符串存储到有权限写入的内存区域,两种常用实现方式:
方案1:用栈上的字符数组存储
// 编译器会自动把字符串字面量的内容拷贝到栈上的数组空间,栈空间可写 char someString[] = "original string"; someString[1] = 'O';
方案2:用堆内存存储
#include <stdlib.h> #include <string.h> // 申请堆内存,堆空间默认可写 char* someString = malloc(strlen("original string") + 1); // 把字符串字面量的内容拷贝到申请的堆内存中 strcpy(someString, "original string"); someString[1] = 'O'; // 用完要手动释放堆内存,避免内存泄漏 free(someString);
内容的提问来源于stack exchange,提问作者user97662
相关产品推荐
相关产品推荐

