我是C初学者,我在尝试实现链表时遇到了这段代码。
struct Node *ptr = malloc(sizeof(*ptr));
节点结构如下所示:
struct Node {
int data;
struct Node *next;
};
我试图理解第一行。似乎malloc(sizeof(*ptr))
已经知道ptr
的内容.左侧到底发生了什么,在调用malloc之前是否发生了?
malloc(sizeof(*ptr))
已经知道ptr
的内容。
其实不然。sizeof
运算符实际上并不计算其操作数(除非它是可变长度数组),它只是查看其类型。 这意味着ptr
实际上并没有取消引用,因此是一种安全的操作。
只有在您想知道大小的类型时,才将偏执与sizeof
一起使用。如果你有一个表达式,比如*ptr
,写就足够了:
struct Node *ptr = malloc(sizeof *ptr); // <- no parenthesis
表达式*ptr
取消引用指针,使其成为struct Node
,这就是sizeof
返回大小的目的。
sizeof
expression
- 返回表达式类型的对象表示形式的大小(以字节为单位)。不会对表达式应用隐式转换。
如果您这样做,它的大小与您获得的大小相同:
struct Node *ptr = malloc(sizeof(struct Node)); // <- parenthesis needed
但为了清楚起见,第一种选择通常更可取。
您需要为声明struct Node
类型的对象分配内存
struct Node {
int data;
struct Node *next;
};
因此,在 malloc 的调用中,您需要指定要为此类型的对象分配的内存大小。函数 malloc 返回指向已分配内存的指针。
所以你可以写
struct Node *ptr = malloc( sizeof( struct Node ) );
另一方面,表达式*ptr
具有结构体 Node 的类型。也就是说,声明的指针ptr
指针类型struct Node *
并且像*ptr
这样的取消引用此类指针会产生类型为struct Node
的表达式。
所以你也可以重写上面的记录,就像
struct Node *ptr = malloc(sizeof(*ptr));
因为在这种情况下sizeof( struct Node )
等同于sizeof( *ptr )
.
也就是说,编译器需要知道运算符的操作数的类型,sizeof
确定该类型对象的大小。