Please consider a heap-allocated array of pointers like this:
Thing** array = malloc(sizeof(Thing*) * array_length);
How can I set all of its members to NULL
?
I can of course do this:
for (int i = 0; i < array_length; i++) {
array[i] = NULL;
}
But I'm wondering if there's a standard function for this.
SO mainly mentions memset
, however I'm not sure it is guaranteed to work on all platforms for this usecase, since as far as I understand it walks the array byte by byte, and not element by element.
Also more generally, what is the standard way to set all values in an array of any type T
, which can be of any size, to some particular value?
I cannot think of any better way to to this than what you already are doing. It's short and clear. It's absolutely nothing wrong with it, and I would not even consider something else.
If it is to save a few lines you can use one of these:
for (size_t i = 0; i < array_length; i++) // No braces
array[i] = NULL;
for (size_t i = 0; i < array_length; i++) array[i] = NULL; // Single
for (size_t i = 0; i < array_length; i++) { array[i] = NULL; } // With braces
But I want to point out that some people have strong opinions about this. I often skip braces for single statement loops. If you use any of these techniques, be prepared for complaints.
You could use memset
, and it will work most of the times. However, the C standard does not require null pointers to be all zeros. Granted, the risk of a failure because of this is minuscule, but why take the risk when the gain is nearly zero? If you ask me, a loop is clearer, because your goal IS to set the pointers to NULL. The loop clearly communicates this.
There are historical examples with non-zero NULL machines: When was the NULL macro not 0?
However, do note that even though NULL is not required to be all zero bits, it IS guaranteed to evaluate to false when used in a Boolean expression. So you can safely use if(!ptr)
to check if a call to malloc
succeeded or not. I explained it in this answer Is NULL always false?
Initializing the array with an explicit loop is the only standard conformant approach that is guaranteed to work correctly on all platforms. Good compilers should be able to convert the loop into whatever is more efficient on the target platform for zero initialization if indeed null pointers are represented with all bits zero there.
If you can assume that all-bits zero is a correct representation of null pointers, which is almost always the case but not guaranteed by the C Standard, you can use a call to memset
or more efficiently, allocate the array with calloc()
:
Thing **array = calloc(array_length, sizeof(*array)); // initialize to all bits zero
This can be more efficient than both the call to memset
and the explicit loop as calloc()
may in some cases assume the memory it gets from the OS to already be zero initialized, as is the case of newly mapped blocks for security reasons.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With