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

C语言中通过指针修改字符串触发总线错误的原因是什么?

问题原因拆解

1. 最初触发bus error的核心原因

你最初的代码里char *hello = "hello"定义的是字符串常量,这类字符串会被编译器放在进程的只读数据段,内存权限是只读,当你在strcopy里尝试向这个地址写入内容时,就会触发非法内存访问,报bus error或者segmentation fault。你这个点的判断是完全正确的。

2. 你的理解误区纠正

你关于「传递指针的值就不能在函数内解引用」的理解是错误的:

  • 指针变量存储的值本身就是内存地址,C语言按值传递指针时,函数内部拿到的就是完整的内存地址值,只要这个地址指向的内存是可读写的,完全可以正常解引用操作。
  • 你最初的代码报错和传递指针的值没有任何关系,完全是因为目标地址指向了只读内存区域。

3. 修改后代码出现编译器警告的原因

你把hello和world修改为栈上的字符数组char hello[] = "hello"是正确的选择,栈内存是可读写的。但调用strcopy时传&hello是多余且错误的:

  • 数组名hello本身在作为函数参数传递时,会自动退化为指向数组首元素的指针,类型就是char *,刚好匹配strcopy的参数要求。
  • &hello的类型是char (*)[6](指向长度为6的字符数组的指针),和strcopy要求的char *类型不匹配,所以编译器会抛出类型不兼容的警告。

正确的可运行代码

void strcopy(char *s, char *t) {
    while(*s++ = *t++) 
        ;
}

int main(int argc, char *argv[]) {
    // 定义栈上字符数组,给足够的空间存储拷贝后的内容
    char hello[10] = "hello";
    char world[] = "world";

    // 直接传数组名即可,自动退化为char*
    strcopy(hello, world);
    return 0;
}

上述代码编译运行不会产生任何报错和警告。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 03:36:04