You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言char数组、字符串字面量指针、指向数组的指针可修改性差异问题

C语言字符数组与字符指针可修改性问题解答

核心前置知识

C标准明确规定修改字符串字面值(代码中直接用双引号包裹的字符串)属于未定义行为,绝大多数编译器实现会把程序内存划分为多个权限不同的段,和字符串相关的核心两类内存段:

  • 只读数据段(.rodata段):编译期确定内容,运行时内存页权限为只读,所有字符串字面值都会存储在这个段。
  • 栈内存:运行时动态分配给局部变量的内存,权限为可读可写。

问题1:char* b="salam"指向的内容为什么不能修改

两种定义的本质区别如下:

  • char a[]="hello":双引号里的"hello"只是初始化模板,编译器会在栈上开辟长度为6的连续内存(包含字符串末尾的终止符\0),把"hello"的内容拷贝到这片栈内存里,数组名a是这片栈内存的首地址别名,操作a本质是修改栈上的拷贝,不受只读限制。
  • char* b="salam":b本身是栈上的指针变量,它存储的是只读数据段中字符串字面值"salam"的首地址。执行b[0]='m'本质是对只读的.rodata段执行写入操作,会被操作系统的内存保护机制拦截,直接触发段错误。
    注意:不可修改的是b指向的.rodata段内存,b本身是可以修改的,比如执行b = a让它指向栈上的数组a是完全合法的。

问题2:char* c=a指向的内容为什么可以修改

指针的本质是存储内存地址的变量,能不能修改指针指向的内容,完全由该地址对应内存的访问权限决定,和指针本身没有关系:

  • 你定义的char* c=a里,c存储的是栈上数组a的首地址,栈内存是可读可写的,所以通过c[0]='r'写入是合法操作。
  • 而之前的char* b="salam"里,b存储的是.rodata段的地址,该段只读,所以不能写入。两者的区别是指向的内存属性不同,不是指针本身有区别。

内容的提问来源于stack exchange,提问作者S MEHDI M

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 13:39:03