struct x {
int *u;
};
struct y {
struct x *z;
};
int main()
{
static y b;
static int g=7;
b.z->u=&g;
}
语句b.z->u=&g
给出了分段错误。如果我删除static
前面的int g
:通过嵌套结构访问指针
int g=7;
b.z->u=&g;
代码正确执行。
struct x {
int *u;
};
struct y {
struct x *z;
};
int main()
{
static y b;
static int g=7;
b.z->u=&g;
}
语句b.z->u=&g
给出了分段错误。如果我删除static
前面的int g
:通过嵌套结构访问指针
int g=7;
b.z->u=&g;
代码正确执行。
它会给你一个分割错误,因为你在做什么是未定义的行为。您正在访问z
结构的指针,而不是对其进行初始化(即,不给它指向的内存空间)。在变量不是静态的情况下,它不会给出分段错误并不重要,因为对未初始化指针的整体访问是错误的。
严格来说,由于'b'被声明为'static',所以保证被初始化为零。 'b.z'保证是一个空指针。当然,行为仍然是不确定的。 – AnT
您从未为您的b.z
分配内存。您的b.z
包含未初始化的垃圾值,这就是为什么试图废除b.z
(在b.z->u
中)会导致分段错误的原因。
P.S.你宣布你的对象static
,这意味着b.z
最初包含一个空值(不是“未初始化的垃圾值”,如上所述)。尽管如此,解引用空指针也是未定义的。
但分配给非静态分配的工作? – karan
@karan:什么是“非静态分配”?如果你删除'静态'?不,它不“工作”。如果它没有崩溃,那只是因为你以某种方式得到了幸运,并且垃圾值最终指向了一些可写的内存,随后你就会破坏它。 – AnT
@karan - 不,它可能会出现*工作,但原因很微妙,事实是您的代码有一个可怕的错误,因为b.z永远不会被初始化。奥利的回答很好。静态的原因澄清你的bug是静态保证零初始化变量。这将b.z设置为NULL指针,并且会得到一个很好的,确定性的崩溃。当b被分配非静态时,它从先前堆栈中的任何内容接收内容。在这种情况下,b.z可以获得值NULL,或者一些非指针值或其他有效指针(然后使用b.z将覆盖另一个指针的内存)。 –
因为b.z
尚未设置为指向任何有用的位置。它目前只是一个NULL
指针。 *
您需要的线沿线的做一些事情:
b.z = malloc(sizeof(*b.z));
第一(即创建一个实际的对象)。
请记住在free
这个点上。
*请注意,这只是因为NULL
是b
声明为static
。如果b
不是static
,它将指向内存中随机的某处。
Downvoter:关心评论? –
看起来像有人不喜欢这个问题,并想要每个人回答它。我想今天在Youtube上没有什么好处。 –
b.z
尚未初始化。您初始化b
有:
static y b;
但其成员场z
仍然是一个空指针(指向这样一些随机的位置)。因此,访问其成员u
会导致分段错误,因为您正在访问一些随机存储器。
我想,这应该工作(没有尝试):
static y b;
static x c;
static int g=7;
b.z = &c;
b.z->u=&g;
为什么你的第二个例子的作品,我不知道。我怀疑这是由于'运气'...
无法理解为什么它会以这种方式发生。也有任何其他的上述分配.. – karan
这个时候的每个答案都指出,b结果的静态分配在bz中设置为未定义的值。事实上,静态保证零初始化内存,所以b.z是NULL。如果你删除了关键字static,那么你会得到一个更糟的错误,其中b.z指向内存中的某个随机位置,也许argv被存储的位置等。 –
@Heath Hunnicutt:不正确。首先,我的回答和评论从一开始就虚构了指针为空。其他答案也是如此。其次,OP在其中一个评论中明确提出了关于同一事物的非静态版本。 – AnT