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

编译运行这段C语言char**示例代码触发段错误是什么原因?

段错误根本原因

你的猜测方向是对的,核心问题是变量类型声明错误,导致初始化逻辑和你预期完全不符,具体拆解:

  • 你声明的char **a是一个普通的指针变量,本身只占存储一个内存地址的空间(64位系统下8字节,32位下4字节),它的作用是存储另一个char*类型变量的地址,根本不是数组。
  • 你写的{"ab", "ac"}是数组专属的聚合初始化语法,只有当你声明的变量是char*类型数组时,编译器才会按顺序给数组的两个元素分别赋值为两个字符串字面量的首地址,分配对应长度的连续内存。
  • 当你强行给char**类型的标量指针用双元素列表初始化时,C语言只会取列表的第一个值给a赋值,第二个值直接被忽略——也就是说a里实际存的是字符串字面量"ab"的首地址(一个char*类型的值,指向字符'a'),类型层级差了一级,正常开编译警告这里就会报类型不匹配的错误。
  • 后续执行*a时,程序会把"ab"开头的若干字节(64位系统下读8字节)当成一个内存地址去访问:"ab"在内存里存储的字节依次是0x61('a')、0x62('b')、0x00(结束符),拼出来的是一个非常低的非法地址(属于系统保留的内存段),用户态程序无权限访问,直接触发段错误,根本执行不到后续偏移取字符的逻辑。
正确实现方式

你如果要实现预期的char*数组(字符串数组)效果,有两种合法写法:

  1. 直接声明指针数组,数组名使用时会自动退化为char**类型,完全匹配你的访问逻辑:
#include <stdio.h>
int main() {
    // 声明长度为2的char*数组,两个元素分别指向两个字符串字面量
    char *a[] = {"ab", "ac"};
    // sizeof(char)标准固定为1,这里*a是数组首元素,即指向"ab"首字符的char*,偏移1字节解引用就是'b'
    printf("%c", *(*a + sizeof(char)));
    return 0;
}
  1. 如果你确实需要单独定义char**类型的指针变量,需要先让它指向一个已经存在的char*数组的首地址,不能直接用初始化列表赋值:
#include <stdio.h>
int main() {
    char *str_arr[] = {"ab", "ac"};
    char **a = str_arr; // 指针a指向char*数组的首元素,类型完全匹配
    printf("%c", *(*a + 1));
    return 0;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 01:39:19