阳间祝福 发表于 2022-8-18 02:40:01

struct 指针 p->member 导致 Segmentation fault 的问题

大家好,我在看 C 的 结构体部分的知识,在自己写代码测试 用结构体指针 p->member 的方式给结构体初始化的时候碰到了 Segmentation fault 的问题:
代码如下:        #include <stdio.h>

int main() {
    char s = 'a';
    struct {
      int len;
      char *str;
    } *p;

    printf("hello world\n");

    p->len = 100;
    p->str = &s;
    printf("*p->str: %c\n", *p->str);

    return 0;
}

运行结果如下:
$ gcc -g lab.c
$ ./a.out
hello world
Segmentation fault (core dumped)

现在神奇的事情是,当我添加一行 初始化一个 int 类型的无关的变量后,程序就能运行了,代码如下:
#include <stdio.h>

int main() {
    char s = 'a';
    struct {
      int len;
      char *str;
    } *p;
    int c = 11;   // 随便一个变量,随便赋一个初值

    printf("hello world\n");

    p->len = 100;
    p->str = &s;
    printf("*p->str: %c\n", *p->str);

    return 0;
}

运行结果如下:
$ gcc -g lab.c
$ ./a.out
hello world
*p->str: a

我不理解。。。反汇编看了一下,第二个代码只是栈那里多了16个字节用来存 int c,其他地方实在没发现有什么线索。。。

所以想问一下这个现象的原因是什么?谢谢大家了!

wp231957 发表于 2022-8-18 06:21:14

狠明显char *str;这里没有分配到空间

jackz007 发表于 2022-8-18 10:44:00

本帖最后由 jackz007 于 2022-8-18 10:51 编辑

      第5~8行代码定义的只是一个指向结构类型的指针,也就是说,对于 32 位的程序而言,只是定义了 4 个字节的空间,用于保存指针变量 p,这个变量的值通常被初始化为 NULL,也就是 0 值,就是说,这个 p 在未被赋值之前,指向的是一个根本不存在的内存地址,所以,当向 p 所指向的地址存取数据的时候,自然就会发生 Segmentation fault 错误了。
      解决方法是在使用 p 之前,先用 malloc() 为 p 分配一个结构体所需要的内存空间,这样,p 就会指向这个内存空间,自然就可以通过 p 正常存取结构数据了。
      还有,既然定义了结构,为什么不定义成员变量,不确定这样做会不会有问题。

阳间祝福 发表于 2022-8-18 12:49:21

wp231957 发表于 2022-8-18 06:21
狠明显char *str;这里没有分配到空间

有道理哦!我把 char *str 换成 int len2 之后,就可以执行了

阳间祝福 发表于 2022-8-18 12:52:10

jackz007 发表于 2022-8-18 10:44
第5~8行代码定义的只是一个指向结构类型的指针,也就是说,对于 32 位的程序而言,只是定义了 4...

是的,在用了 malloc() 之后就没报错了!谢谢

报错的问题解决了,那第2个代码的现象您有什么看法吗?

wp231957 发表于 2022-8-18 13:10:50

阳间祝福 发表于 2022-8-18 12:52
是的,在用了 malloc() 之后就没报错了!谢谢

报错的问题解决了,那第2个代码的现象您有什么看法吗?

那有啥可说的,就是本来指针是没有地方可指
你在那里增加了一个变量,使得指针有了方向
虽然那里的数据并不是期待数据,然这并不是被认可的写法,故该写法无任何参考和研究的意义
页: [1]
查看完整版本: struct 指针 p->member 导致 Segmentation fault 的问题