struct Node *ptr = malloc(sizeof(*ptr)) 是如何工作的?

How does struct Node *ptr = malloc(sizeof(*ptr)) work?

我是 C 初学者,我在尝试实现链表时遇到了这段代码。

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

节点结构如下所示:

    struct Node {
        int data;
        struct Node *next;
    };

我正在尝试理解第一行。似乎 malloc(sizeof(*ptr)) 已经知道 ptr 的内容。左侧到底发生了什么,是在调用 malloc 之前发生的吗?

如果您想知道 类型 的大小,请仅将括号与 sizeof 一起使用。如果你有一个表达式,比如*ptr,这样写就够了:

struct Node *ptr = malloc(sizeof *ptr);         // <- no parenthesis

表达式 *ptr 取消引用指针,因此它变成了 struct Node,这就是 sizeof 返回大小的原因。

sizeofexpression - Returns the size, in bytes, of the object representation of the type of expression. No implicit conversions are applied to expression.

如果您这样做,它的尺寸与您得到的尺寸相同:

struct Node *ptr = malloc(sizeof(struct Node)); // <- parenthesis needed

但为了清晰起见,第一种选择通常更可取。

It seems as if malloc(sizeof(*ptr)) already knows the contents of ptr.

其实不是。 sizeof 运算符实际上并不评估其操作数(除非它是可变长度数组),它只是查看其类型。这意味着 ptr 实际上并没有取消引用,因此是一个安全的操作。

您需要为struct Node声明为

类型的对象分配内存
struct Node {
    int data;
    struct Node *next;
};

所以在malloc的调用中需要指定为该类型的对象分配的内存大小。函数 malloc returns 指向已分配内存的指针。

所以你可以这样写

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

另一方面,表达式 *ptr 的类型为 struct Node。也就是说,声明的指针 ptr 具有指针类型 struct Node * 并且取消引用像 *ptr 这样的指针会产生类型 struct Node.

的表达式

所以你也可以像这样重写上面的记录

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

因为在这种情况下 sizeof( struct Node ) 等同于 sizeof( *ptr ).

也就是说,编译器需要知道运算符的操作数类型 sizeof,以确定该类型对象的大小。