为什么malloc(sizeof(指针))有效?

以下代码工作正常:

#include  #include  int main() { struct node{ int a, b, c, d, e; }; struct node *ptr = NULL; printf("Size of pointer ptr is %lu bytes\n",sizeof (ptr)); printf("Size of struct node is %lu bytes\n",sizeof (struct node)); ptr = (struct node*)malloc(sizeof (ptr)); //Line 1 // ptr = (struct node*)malloc(sizeof (struct node)); //Line 2 ptr->a = 1; ptr->b = 2; ptr->c = 3; ptr->d = 4; ptr->e = 5; printf("a: %d, b: %d, c: %d, d: %d, e: %d\n", ptr->a,ptr->b,ptr->c,ptr->d,ptr->e); return 0; } 

符合时:

 gcc -Wall file.c 

我的问题是:为什么这样好?

malloc分配在其参数中指定的字节数。 这里sizeof ptr在我的64位linux机器上是8个字节。 我认为malloc将提供8个字节但是它如何访问所有变量a,b,c,d,e? 是仅使用gcc还是我缺少标准C的东西?

据我所知,“第2行”应该在那里而不是“第1行”,但任何一行都可以正常工作。 为什么?

你在这里有未定义的行为。

malloc将分配8个字节(如你所说),但这个演员是“坏”:

 ptr = (struct node*)malloc(sizeof (ptr)); 

在这一行之后, ptr将指向一个内存块,它只有8个分配的字节,其余的是一些“随机”字节。 所以,制作

 ptr->a = 1; ptr->b = 2; ptr->c = 3; ptr->d = 4; ptr->e = 5; 

你实际上改变了一些内存,而不仅仅是malloc分配的malloc

换句话说,你正在重写记忆,你不应该触摸。

第1行不正确, 不会分配足够的空间。 如果以后可以访问结构成员,那只是因为C不会阻止您访问不属于您的内存。

如果没有为整个结构分配足够的空间,则访问ptr->bptr-c等是未定义的行为,下次运行代码时可能会崩溃,或者最终可能会覆盖数据你计划的另一部分。

要演示此问题,请在第一个struct node之后立即分配第二个struct node 。 这不能保证certificate问题,但您可能会看到类似于以下结果:

 struct node *ptr = NULL; struct node *ptr2 = NULL; ptr = (struct node*)malloc(sizeof (ptr)); // Your Line 1 ptr2 = malloc(sizeof(struct node)); // alloc another struct on the heap ptr->a = 1; ptr->b = 2; ptr->c = 3; ptr->d = 4; ptr->e = 5; ptr2->a = 11; ptr->b = 12; ptr->c = 13; ptr->d = 14; ptr->e = 15; printf("ptr: a: %d, b: %d, c: %d, d: %d, e: %d\n", ptr->a, ptr->b, ptr->c, ptr->d, ptr->e); printf("ptr2: a: %d, b: %d, c: %d, d: %d, e: %d\n", ptr2->a, ptr2->b, ptr2->c, ptr2->d, ptr2->e); 

输出:

 ptr: a: 1, b: 2, c: 3, d: 4, e: 11 ptr2: a: 11, b: 12, c: 13, d: 14, e: 15 

请注意, ptr->e已通过赋值给ptr2->a进行了修改,因此您可以看到一个不正确分配的结构正在踩踏另一个的内存。 这肯定不是你想要的。

malloc只分配8个字节,但这并不能阻止你访问超出该字节的内存。 您可能会损坏堆并可能会写入其他对象。 程序的行为未定义。

ptr->a = 1; ptr->b = 2; ptr->c = 3; ptr->d = 4; ptr->e = 5; ptr->a = 1; ptr->b = 2; ptr->c = 3; ptr->d = 4; ptr->e = 5; 您正在访问malloc分配的内存之外。
这是缓冲区溢出的情况,并导致undefined behaviour

有可能是因为

  C and C++ provide no built-in protection against accessing or overwriting data in any part of memory. 

所以,它可能会在某个时候工作,有时可能会使程序崩溃。