以下代码可以正常使用:
#include <stdio.h>
#include <stdlib.h>
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
分配在其参数中指定的字节数。这里{64} linux机器上sizeof ptr
是8个字节。我以为malloc
将提供8个字节但是它如何访问所有变量a,b,c,d,e?是仅使用gcc还是我缺少标准C的东西?
据我所知,“Line 2”应该在那里而不是“Line 1”,但是任何一条线路都能正常工作。为什么呢?
答案 0 :(得分:11)
这里有未定义的行为。
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
分配的记忆。
换句话说,你正在重写记忆,你不应该碰。
答案 1 :(得分:8)
第1行不正确,不会分配足够的空间。如果以后可以访问结构成员,那只是因为C不会阻止您访问不属于您的内存。
当您没有为整个结构分配足够的空间时,访问ptr->b
,ptr-c
等是未定义的行为,下次运行代码时可能会崩溃,或者您最终可能会覆盖程序另一部分的数据。
要演示此问题,请在第一个之后立即分配第二个struct node
。这不是保证来证明问题,但您可能会看到与以下内容类似的结果:
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
的赋值修改,因此您可以看到一个不正确分配的结构正在踩到另一个的内存。这当然不是你想要的。
答案 2 :(得分:3)
malloc
仅分配8个字节,但这并不能阻止您访问超出该字节的内存。您可能会损坏堆并可能会写入其他对象。程序的行为未定义。
答案 3 :(得分:2)
在ptr->a = 1; ptr->b = 2; ptr->c = 3; ptr->d = 4; ptr->e = 5;
中,您正在访问malloc分配的内存之外
这是buffer overflow的情况,会导致undefined behaviour
。
这是可能的,因为
C and C++ provide no built-in protection against accessing or overwriting data
in any part of memory.
所以,它可能会在某个时候工作,有时可能会使程序崩溃。