Uu6p94cFbGXx7duC
V2EX  ›  C

C 语言新手请教一个段错误问题

  •  
  •   Uu6p94cFbGXx7duC · Apr 29, 2021 · 3347 views
    This topic created in 1838 days ago, the information mentioned may be changed or developed.
    #include <stdio.h>
    #include <stdlib.h>
    
    struct Child {
    };
    
    struct Parent {
        struct Child *child;
    };
    
    int main(void)
    {
        struct Child *child = (struct Child *)malloc(sizeof(struct Child));
        struct Parent *parent;
    
        parent->child = child;
    
        return 0;
    }
    

    报错为:bash: line 1: 30009 Segmentation fault: 11 "~/Code/hello_c/main",但是如果把这两行交换,就不会报错,如下:

        struct Parent *parent;
        struct Child *child = (struct Child *)malloc(sizeof(struct Child));
    

    想不通是为啥,特来请教。

    Supplement 1  ·  Apr 29, 2021
    突然懂了,parent 里面的指针需要分配内存。关帖。
    21 replies    2021-05-04 23:28:51 +08:00
    justou
        1
    justou  
       Apr 29, 2021
    你的 parent 指针没分配内存
    newmlp
        2
    newmlp  
       Apr 29, 2021   ❤️ 1
    这。。。也太新手了
    Jf35jxN3fwBXyeLh
        3
    Jf35jxN3fwBXyeLh  
       Apr 30, 2021
    哈哈哈,果然是新手
    araraloren
        4
    araraloren  
       Apr 30, 2021
    这。。建议学习 rust 去吧
    Uu6p94cFbGXx7duC
        5
    Uu6p94cFbGXx7duC  
    OP
       Apr 30, 2021 via iPhone   ❤️ 1
    各位,我才学了一天,大可不必冷嘲热讽。原以为 v 站风气会好一点,看来也不过如此。顺便请教一下,如何注销账号。
    rbut
        6
    rbut  
       Apr 30, 2021
    脾气好像有点大。
    lance6716
        7
    lance6716  
       Apr 30, 2021 via Android   ❤️ 1
    自己能说自己是新手,别人说不行🤔
    JamesMackerel
        8
    JamesMackerel  
       May 1, 2021 via iPhone
    我有点好奇,为啥交换就不会错了……
    killeder
        9
    killeder  
       May 1, 2021
    newbie
    sunnywqf
        10
    sunnywqf  
       May 2, 2021 via iPhone
    @JamesMackerel 同好奇,一会儿用 Windows 试试
    sunnywqf
        11
    sunnywqf  
       May 2, 2021
    @JamesMackerel #8 估计楼主说错了吧, 用 https://gcc.godbolt.org/ 看了下生成的 arm 汇编, 交换这两行,没有任何的变化 .
    sunnywqf
        12
    sunnywqf  
       May 2, 2021
    多执行几遍呢, 是不是会有出错的时候.
    zjsxwc
        13
    zjsxwc  
       May 2, 2021
    换不换顺序都会报错

    [zjsxwc@manjaro]$ git diff q.c q2.c
    diff --git a/q.c b/q2.c
    index 032ef4a..517a6db 100644
    --- a/q.c
    +++ b/q2.c
    @@ -10,8 +10,8 @@ struct Parent {

    int main(void)
    {
    - struct Child *child = (struct Child *)malloc(sizeof(struct Child));
    struct Parent *parent;
    + struct Child *child = (struct Child *)malloc(sizeof(struct Child));

    parent->child = child;

    [zjsxwc@manjaro]$ gcc -o q.out q.c
    [zjsxwc@manjaro]$ gcc -o q2.out q2.c
    [zjsxwc@manjaro]$ ./q.out
    Segmentation fault (core dumped)
    [zjsxwc@manjaro]$ ./q2.out
    Segmentation fault (core dumped)
    yolee599
        14
    yolee599  
       May 3, 2021
    这个行为很危险啊,函数内定义的变量 parent 没初始化的时候是不确定的,也就是说你给一个不确定的地址赋值,百分百造成内存溢出。
    csfreshman
        15
    csfreshman  
       May 3, 2021
    正确的写法是:
    int main(void)
    {
    struct Child *child = (struct Child *)malloc(sizeof(struct Child));
    struct Parent parent;

    parent.child = child;
    printf("hello,world");
    return 0;
    }

    交换顺序也不会正确运行,最简单的写法是声明栈变量 parent,当然也可以分配堆变量(malloc),你的写法没有分配内存,直接对一个未初始化的指针操作是未定义行为。
    BrettD
        16
    BrettD  
       May 4, 2021
    新手脾气还这么大,牛气上天了
    ch2
        17
    ch2  
       May 4, 2021
    交换后没报错只是你运气好,这种写法是完全错误的
    crazytec
        18
    crazytec  
       May 4, 2021 via Android
    兄弟,我觉得这种问题直接上 stackoverflow 或者在各种群里问就行了(反正 rust 有中国 tg 非官方群,c 不知道有没有)。我个人的见解是 V2EX 和知乎的定位比较类似,都是偏向生活(比如讨论一下新闻或者是自己的人生经验)而非严肃的编程话题(比如说代码哪里错了之类的)。v2ex 的主页、热门机制都是为了更多人看到一个帖子并且讨论,因此很多情况下点进帖子的人根本没想解答你的疑惑(甚至连 c 语言怎么写都不知道),单纯就是想发表一下自己的意见。在这种偏技术的帖子里,他们就只好喷一下“新手”这个词。不用太放在心上就行了🙂
    Kasumi20
        19
    Kasumi20  
       May 4, 2021
    struct Parent *parent;

    这个应该是为定义行为吧?有的编译器会设为 0,所以段错误
    有的是个不处理的野指针,所以可能不报错。
    raysonx
        20
    raysonx  
       May 4, 2021 via iPhone
    @Kasumi20 全局变量的话会被初始化为 0,非全局变量的初始值是未定义的。
    gBurnX
        21
    gBurnX  
       May 4, 2021
    @Uu6p94cFbGXx7duC

    1.冷嘲热讽的人在哪都有。前两天国内微软 2 把手下面的一个小屁孩,带着两个小伙伴,在某和一个 IT 细分方向新晋领域的老板吵了几天架。他们那种层次,同样有冷嘲热讽的。

    2.你问问题,有高手回复,你达到目的就好。没必要注销账号。这个论坛里还是有很多大神潜伏着,时不时他们就会发点重要心得,你注销账号,不来这个论坛了,其实是你自己的损失。

    3.另外,你可以看看那些嘲讽你的小伙伴,点开他们的资料,看看他们的提问与回复。看完后,你再想想,为这种层次的人生气,值得嘛?
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   985 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 63ms · UTC 20:46 · PVG 04:46 · LAX 13:46 · JFK 16:46
    ♥ Do have faith in what you're doing.