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

C语言示例中传入char*参数可被正常修改的原因是什么?

C语言char*可写性问题解答

核心误区澄清

你对char*的认知存在偏差:char*本身从来不是只读类型,能否修改其指向的内容,完全由指针指向的内存区域的读写权限决定,和指针类型没有直接关系。


为什么修改sortString参数为char*后仍能正常运行

1. 函数参数的隐式退化规则

C语言中,数组作为函数参数传递时,会自动退化为指向数组首元素的指针。也就是说,你写的void sortString(char string[50])和void sortString(char *string)在编译器层面是完全等价的,改参数类型前后的代码没有本质区别,运行结果自然一致。

2. 指向的内存是可写的

你传入sortString的参数是buf,对应定义是char buf[50],这是在程序栈空间分配的临时数组,栈空间的内存默认是可读写的。即使退化为char*指针,指针指向的仍然是可读写的栈内存,修改内容当然不会报错。


为什么char *read = "Hello";修改会触发总线错误

这里触发错误的原因和char*类型无关,问题出在你指向的内容是字符串字面量:

  • C标准明确规定,修改字符串字面量属于未定义行为。主流编译器实现中,所有双引号包裹的字符串字面量都会被存放在进程的.rodata(只读数据段),该内存段的页权限被设置为只读,任何写入操作都会被操作系统拦截,触发异常(你遇到的总线错误、常见的段错误都是这类权限异常的表现)。
  • 这种场景下只是char*指针刚好指向了只读内存,并不是char*本身只能指向只读内存。

两个场景的核心差异对比

  • 正常运行的场景:char*指向栈/堆上分配的可读写内存(栈数组、malloc申请的内存都属于这类),具备写入权限。
  • 报错的场景:char*指向只读数据段的字符串字面量,不具备写入权限。

举个简单的验证例子:

// 写法1:指向字符串字面量,不可修改
char *ptr1 = "Hello";
// ptr1[0] = 'B'; 报错

// 写法2:栈数组,把字符串字面量内容拷贝到栈上,可修改
char ptr2[] = "Hello";
ptr2[0] = 'B'; // 正常运行,输出Bello

内容的提问来源于stack exchange,提问作者David

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 01:54:06