之前使用memset还需要设置ptr为NULL吗?

Do I still need to set ptr to NULL if I use memset earlier?

例如:

struct sth {
    int  t;
    char *p;
    struct sth *next;
}

初始化代码:

struct sth *data = malloc(sizeof(*data));
memset(data, 0, sizeof(*data));
data->t = 0;        // A
data->p = NULL;     // B
data->next = NULL;  // C

既然用了memset,还需要写A, B, C吗?

这只是一个示例,我有一个包含很多指针的结构...

不需要。您还可以使用 calloc() instead of the malloc(), it will set memory to zero without requiring an additional call to the memset() and may be faster.

"Do I still need to set ptr to NULL if I use memset() earlier?"

如果您希望您的程序完全符合标准,那么可以,因为 memset() 将每个字节设置为 0,这与将 NULL 设置为指针不同。 (假设 ptr 等同于结构 sth 内部的 p

引用当前 C 标准 ISO:IEC 9899:2018 (C18),第 7.22.3.5/2 节 - calloc 函数:

"The space is initialized to all bits zero. 302)"

"302 - Note that this need not be the same as the representation of floating-point zero or a null pointer constant."


"Since I have used memset(), do I still need to write A, B, C"?

A. 是多余的,只要 t 不是浮点类型的对象,因为它们可以具有浮点零值,可能不会将所有位都设置为 0。如果 t 是 f.e。 floatdouble A. 类型将很有用且适合符合标准。

B.C. 是合适的,因为根据标准将每个字节设置为 0 不一定也将指针设置为 NULL,如果您明确想将它们分配给 NULL(尽管在大多数系统上应该如此)。

请注意,calloc() 可能更方便,性能也更快,因为它分配内存并立即将其每一位初始化为 0:

struct sth *data = calloc(sizeof(*data));

但在这里,pnext 不需要是 NULL

一个更简单的版本是:

struct sth *data = malloc(sizeof(*data));
*data = (struct sth){0};

如果平台的结构成员全为零,您的编译器可以将其优化为 calloc 调用。

使用 memset() 将结构设置为所有位零有效地将所有整数成员设置为 0。 C 标准指定其他成员将有一个值,该值可能对应于也可能不对应于将它们手动设置为 0 的效果。但在所有当前的架构上都是如此,而且未来任何新处理器都不太可能背离这一惯例。所以实际上你是安全的。

另请注意,您应该使用 calloc() 分配一个初始化为所有位为零的对象:

struct sth *data = calloc(1, sizeof(*data));