Can memset() be called with a null pointer if the size is 0?

回眸只為那壹抹淺笑 提交于 2019-12-04 23:12:47

Here is the glibc declaration:

extern void *memset (void *__s, int __c, size_t __n) __THROW __nonnull ((1));

The __nonnull shows that it expects the pointer to be non-null.

Edit Re:

I added this later: Assume that malloc() never fails. The question is only if size can be 0

I see. So you only want things to be secure if the pointer is NULL and the size is 0.

Referring to the POSIX docs

No, it is not specified that it should be safe to call memset with a NULL pointer (if you called it with zero count or size... that'd be even more 'interesting', but also not specified).

Nothing about it is even mentioned in the 'informative' sections.

Note that the first link mentions

The functionality described on this reference page is aligned with the ISO C standard. Any conflict between the requirements described here and the ISO C standard is unintentional. This volume of IEEE Std 1003.1-2001 defers to the ISO C standard

Update I can confirm that the ISO C99 standard (n1256.pdf) is equally brief as the POSIX docs and the C++11 spec just refers to the ansi C standard for memset and friends.

Here's what the C99 standard says about this:

7.1.4 "Use of library functions

If an argument to a function has an invalid value (such as a value outside the domain of the function, or a pointer outside the address space of the program, or a null pointer, or a pointer to non-modifiable storage when the corresponding parameter is not const-qualified) or a type (after promotion) not expected by a function with variable number of arguments, the behavior is undefined.

7.21.1 "String function conventions" (remember that memset() is in string.h)

Where an argument declared as size_t n specifies the length of the array for a function, n can have the value zero on a call to that function. Unless explicitly stated otherwise in the description of a particular function in this subclause, pointer arguments on such a call shall still have valid values, as described in 7.1.4.

7.21.6.1 "The memset function"

The memset function copies the value of c (converted to an unsigned char) into each of the first n characters of the object pointed to by s.

So strictly speaking, since the standard specifies that s must point to an object, passing in a null pointer would be UB. Add the check (the cost compared to the malloc() will be vanishingly small). On the other hand, if you know the malloc() cannot fail (because you have a custom one that terminates), then obviously you don't need to perofrm the check before calling memset().

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!