这是我的结构定义
struct node
{
int value;
struct node *next;
}
我尝试使用此
分配内存struct node *head1=(node *)(malloc(sizeof(struct node)));
和这个
struct node *head2=(node *)(malloc(sizeof(struct node *)));
第一个是分配内存,大小等于" node"第二个分配内存等于指针的大小。 但是它们对我来说都非常有效。 我的意思是我能够访问
head1-> value
和
head2->value
他们俩都一样吗?
答案 0 :(得分:1)
不,他们不一样。
第一个有足够的内存分配容纳一个完整的结构,第二个只有足够的内存用于指针。通过执行head2->value
您将访问未分配的内存并导致未定义的行为。
事实上你可以"使用" head2->value
没有分配任何内存(并且没有为head2
分配任何值)。你不会得到一个编译时错误,你甚至可能没有注意到它在运行时,但如果你有足够大的应用程序,你最终会看到奇怪的事情开始发生。
答案 1 :(得分:1)
不,只有第一个是正确的。
在第二种情况下,您分配的内存少于数据结构占用的内存。当您访问value
时,您完全没问题,因为value
位于struct
的开头,并且在您分配的内容中。另一方面,访问next
将使用超出您分配的内存。由于内存分配的工作方式,看起来很可能也很有效。在大多数情况下,给予您的内存将位于分配给您的进程的页面中间,并且属于您的进程的页面内的访问不会导致崩溃,因此如果您尝试读取或写入{{1在大多数情况下,它似乎可以工作(但在极少数情况下,您的分配可能恰好位于页面的末尾,在这种情况下对next
的访问会崩溃)。但是,这不会分配给您的对象的内存,并且可能很容易被其他东西使用。因此,写入next
可能最终会破坏您分配的其他一些对象。
总而言之,第二次分配是错误的,即使它似乎有效。