V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
ReputationZh
V2EX  ›  C

在外网看到一个比较好玩的问题,一下没反应过来。

  •  
  •   ReputationZh · 2021-11-01 17:18:59 +08:00 · 3671 次点击
    这是一个创建于 878 天前的主题,其中的信息可能已经有所发展或是发生改变。
    #include <stdio.h>
    
    int a = 12345;
    
    void test(int *temp)
    {
        temp = &a;
    }
    
    int main(int argc, char const *argv[])
    {
    
        int *b = NULL;
    
        test(b);
    
        printf("%d\n",  a);
        printf("%d\n", *b);
    
        return 0;
    }
    

    return

    12345    
    Segmentation fault    
    

    为什么段错误呢?

    14 条回复    2022-04-26 16:34:57 +08:00
    AoEiuV020
        1
    AoEiuV020  
       2021-11-01 17:24:24 +08:00
    这不是老生常谈的传值传引用的问题么,c 语言入门书应该都有强调这些问题吧,
    fkdog
        2
    fkdog  
       2021-11-01 17:29:48 +08:00
    test()里 temp 只是一个形参,
    ReputationZh
        3
    ReputationZh  
    OP
       2021-11-01 17:43:41 +08:00
    @fkdog 这个解释可以
    Hallelu
        4
    Hallelu  
       2021-11-01 17:45:07 +08:00
    temp = &a; 并没有改变 b 的指向
    ch2
        5
    ch2  
       2021-11-01 17:49:56 +08:00
    test(b);//这一行不起任何作用
    ryd994
        6
    ryd994  
       2021-11-01 18:02:13 +08:00 via Android
    把书看懂 || gdb 里跑一趟
    这两样你做了任一样就不会有这个问题
    gdb 里跑一圈就明白的事
    CreSim
        7
    CreSim  
       2021-11-01 18:08:33 +08:00 via Android
    显然你需要传指针的指针。
    ligiggy
        8
    ligiggy  
       2021-11-01 18:16:11 +08:00
    temp 是形参。因为传递的是 null ,要想赋值,可以传递 指针的指针,然后 new 一个对象同时赋值即可

    传入 int **temp ,然后赋值为*temp = new int(a);
    0Vincent0Zhang0
        9
    0Vincent0Zhang0  
       2021-11-01 19:02:51 +08:00 via Android
    int a = 12345 //申请一个存放 int 的盒子
    int *b = NULL //申请了一个存放 int 盒子位置的 b 盒子,盒子里面放着 0 这个值
    test(b) //把 b 盒子的内容 0 传给 test
    // 进入 test 后 temp = b 盒子的内容,就是 0
    temp = &a //把 a 盒子的位置传给 temp
    printf("%d\n", a); //打印 a 盒子的内容
    printf("%d\n", *b); //打印 b 盒子内容 0 所指向的盒子里面的内容,因为访问不到 0 位置的盒子内容,所以报错了。

    在这里,test 无法改变 b 盒子的内容,因为传给 test 的只是 b 盒子的内容,而要改变 b 盒子的内容则需要传 b 盒子的位置。

    例如这样改:
    void test(int **temp){ *temp = &a }
    test(&b);
    Jooooooooo
        10
    Jooooooooo  
       2021-11-01 19:26:06 +08:00
    temp 变了啊
    Brian1900
        11
    Brian1900  
       2021-11-01 22:17:48 +08:00
    想要修改一级指针的值,需要将函数参数修改为二级指针,否则函数将拷贝一份新的一级指针,修改的是新指针的值而不是 b 的值
    anzu
        12
    anzu  
       2021-11-02 10:53:33 +08:00
    把指针全去了,就不影响理解了,b 还是 b 。所以很多语言表面上都隐藏了指针的概念。
    GrayXu
        13
    GrayXu  
       2021-11-02 11:21:51 +08:00
    《大一 C 语言课程》
    Kasumi20
        14
    Kasumi20  
       2022-04-26 16:34:57 +08:00
    访问内存 0x0000000000000000 ,能不段错误吗?
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   3617 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 30ms · UTC 05:01 · PVG 13:01 · LAX 22:01 · JFK 01:01
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.