C 通过嵌套结构访问指针

C 通过嵌套结构访问指针,c,pointers,static,structure,C,Pointers,Static,Structure,语句b.z->u=&g给出了一个分段错误。如果我删除int g前面的静态: struct x { int *u; }; struct y { struct x *z; }; int main() { static y b; static int g=7; b.z->u=&g; } 代码执行正确 它会给您一个分段错误,因为您所做的是未定义的行为。您正在访问结构的z指针,但没有初始化它(也就是说,没有给它一个指向的内存空间)。在变量不是静态的情况下,它不会给您

语句
b.z->u=&g
给出了一个分段错误。如果我删除
int g
前面的
静态

struct x {
  int *u;
};

struct y {
  struct x *z;
};

int main()
{
  static y b;
  static int g=7;
  b.z->u=&g;
}

代码执行正确

它会给您一个分段错误,因为您所做的是未定义的行为。您正在访问结构的
z
指针,但没有初始化它(也就是说,没有给它一个指向的内存空间)。在变量不是静态的情况下,它不会给您一个分段错误这一事实并不重要,因为对未初始化指针的整个访问都是错误的。

它会给您一个分段错误,因为您所做的是未定义的行为。您正在访问结构的
z
指针,但没有初始化它(也就是说,没有给它一个指向的内存空间)。如果变量不是静态的,它不会给您一个分段错误这一事实并不重要,因为对未初始化指针的整个访问是错误的。

您从未为
b.z
分配内存。您的
b.z
包含未初始化的垃圾值,这就是为什么尝试取消引用
b.z
(在
b.z->u
)会导致分段错误


另外,您声明了对象
static
,这意味着
b.z
最初包含一个空值(而不是我上面提到的“未初始化垃圾值”)。然而,取消对空指针的引用也是未定义的。

您从未为
b.z
分配过内存。您的
b.z
包含未初始化的垃圾值,这就是为什么尝试取消引用
b.z
(在
b.z->u
)会导致分段错误


另外,您声明了对象
static
,这意味着
b.z
最初包含一个空值(而不是我上面提到的“未初始化垃圾值”)。然而,取消对空指针的引用也是未定义的。

因为
b.z
没有被设置为指向任何有用的地方。它当前只是一个
NULL
指针*

您需要按照以下思路做一些事情:

int g=7;
b.z->u=&g;  
首先(即创建实际对象)

记得在某个时候释放这个



*请注意,它仅为
NULL
,因为
b
声明为
static
。如果
b
是非
静态的
,它将指向内存中的某个随机位置。

因为
b.z
没有设置为指向任何有用的位置。它当前只是一个
NULL
指针*

您需要按照以下思路做一些事情:

int g=7;
b.z->u=&g;  
首先(即创建实际对象)

记得在某个时候释放这个



*请注意,它仅为
NULL
,因为
b
声明为
static
。如果
b
是非
静态的
,它将指向内存中的某个随机位置。

b.z
尚未初始化。您可以使用以下命令初始化
b

b.z = malloc(sizeof(*b.z));
但是它的成员字段
z
仍然是空指针(指向某个随机位置)。因此,当您访问一些随机内存时,访问其成员
u
会导致分段错误

我想这样应该行得通(没有尝试):


我不知道你的第二个例子为什么有效。我怀疑这是因为“运气”…

b.z
尚未初始化。您可以使用以下命令初始化
b

b.z = malloc(sizeof(*b.z));
但是它的成员字段
z
仍然是空指针(指向某个随机位置)。因此,当您访问一些随机内存时,访问其成员
u
会导致分段错误

我想这样应该行得通(没有尝试):


我不知道你的第二个例子为什么有效。我怀疑这是因为“运气”…

无法理解这种情况发生的原因。上述分配是否还有其他选择。此时的每个答案都表明,b的静态分配导致b.z设置为未定义的值。实际上,static保证零初始化内存,因此b.z为空。如果删除关键字static,则会出现更糟糕的错误,其中b.z指向内存中的某个随机位置,可能是存储argv的位置,等等@Heath Hunnicutt:不是真的。首先,我的回答和评论实际上从一开始就表明指针是空的。其他答案也是如此。其次,OP在其中一条评论中明确询问了同一事物的非静态版本。无法理解为什么会发生这种情况。上述分配是否还有其他选择。此时的每个回答都表明,静态分配b会导致b.z设置为未定义的值。实际上,static保证零初始化内存,因此b.z为空。如果删除关键字static,则会出现更糟糕的错误,其中b.z指向内存中的某个随机位置,可能是存储argv的位置,等等@Heath Hunnicutt:不是真的。首先,我的回答和评论实际上从一开始就表明指针是空的。其他答案也是如此。第二,OP在一条评论中明确询问了同一事物的非静态版本。@karan:什么是“非静态分配”?如果您删除
静态
?不,它不起作用。如果它没有崩溃,那仅仅是因为你运气好,垃圾值指向某个可写内存,然后你就把它销毁了。@karan-不。它看起来可以工作,但原因很微妙,事实是你的代码有一个可怕的错误,因为b.z从来没有初始化过。奥利的回答很好。static澄清错误的原因是static保证零初始化变量。这将b.z设置为空指针,您将得到一个很好的确定性崩溃。当b被分配为非静态时,它从堆栈上以前的内容接收内容。在这种情况下,b.z可以获得NULL值,或者一些非点