vego
vego

Reputation: 1059

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

For example:

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

And the init code:

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

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

This is just a sample, I have a struct with lots of pointers...

Upvotes: 3

Views: 428

Answers (4)

chqrlie
chqrlie

Reputation: 144951

Setting the structure to all bits zero with memset() effectively sets all integer members to 0. The C Standard specifies that other members will have a value which may or may not correspond to the effect of setting them to 0 manually. But on all current architectures it is the case, and it seems extremely unlikely that any new processor will depart from this convention in the future. So in practice you are safe.

Note also that you should use calloc() to allocate a object initialized to all bits zero:

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

Upvotes: 0

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

If you want your program to be fully standard-compliant, then yes, as memset() set each byte to 0, which is different to setting NULL to a pointer. (Assuming ptr is equivalent to p inside of the structure sth).

Quote from the current C standard ISO:IEC 9899:2018 (C18), Section 7.22.3.5/2 - The calloc function:

"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. is redundant, as soon as t is not an object of floating-point type as those can have a floating-point zero value, which may not have all bits set to 0. If t were f.e. of type float or double A. would be useful and appropriate to be standard conform.

B. and C. are appropriate, since according to the standard setting each byte to 0 does not necessarily also set the pointers to NULL, if you explicitly want to have them assigned to NULL (although it should on most systems).

Note that calloc() might be more convenient and also faster in performance as it allocates memory and immediately initialize each bit of it to 0:

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

But again here, p and next do not need to be NULL.

Upvotes: 2

M.M
M.M

Reputation: 141628

A simpler version is:

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

Your compiler can optimize this to a calloc call if the platform has all-bits-zero for the struct members .

Upvotes: 0

bobah
bobah

Reputation: 18864

No need. You can also use the calloc() instead of the malloc(), it will set memory to zero without requiring an additional call to the memset() and may be faster.

Upvotes: 3

Related Questions