tags:

views:

1929

answers:

7
+3  Q: 

C : static array

I need to have a static void* array[1024]; in a library and i need to have it set to NULL for every entries.

My question is about the best way to set the entire array to NULL, is a memset (array, NULL, sizeof (void*) * 1024) the best solution?

A: 

Nope, it's wrong. You aren't considering the size of each element.

memset(array, 0, sizeof(array)); // this works only on static arrays.

Generally you should use:

memset(array_reference, 0, size_of_array * sizeof(array_element_type));
Mehrdad Afshari
ok, but my question was about the use of memset, not its args.
claferri
claferri: The first line works for your case. The second line is more general info (to note that memset requires the size of array in bytes, not the number of elements)
Mehrdad Afshari
A: 

No, you want:

memset( array, NULL, sizeof(void *) * 1024 );
anon
ok, but my question was about the use of memset, not its args.
claferri
@zabzonk: that's bogus - `memset()` will convert to `unsigned char` before copying, so using `NULL` as argument results in undefined behaviour!
Christoph
@clafern But the values for the arguments you used were wrong!@christoph Not in C+++ :-)
anon
-1, for reasons given by others, and for the ultra-silly size argument. In this case, where array is a static "true" array (not a pointer), a plain sizeof array is best.
unwind
+8  A: 
static void* array[1024] = {0};

or, as kmkaplan points out in the comment, just:

static void* array[1024];

although I prefer the first solution just to remind me that it's set to zeros (the compiler shouldn't generate any code for this unless it's brain-dead).

You don't need to memset it at all since file-level variables are initialized to zero anyway.

If you need to reset them to NULLs at some point after startup, use:

memset(array, 0, sizeof(array));

This works on most platforms (every one I've ever seen and that's quite a lot) since the null pointer is usually zero bits. But the standard doesn't guarantee this so, on those obscure platforms, it's safer to do:

for (i = 0; i < sizeof(array) / sizeof(void*); i++)
    array[i] = NULL;
paxdiablo
is it an implicit call to memset?
claferri
Note that you do not even need to specify the "= {0}" part.
kmkaplan
It only works for initialization. You might need to use memset in a library function to reset the values at runtime.
Mehrdad Afshari
btw, no offense :) just wanted to remind you of the fact about teh null pointer not always being all-zero :)
Johannes Schaub - litb
No probs, litb, modified to correct.
paxdiablo
+18  A: 

static pointers are automatically initialized to NULL. See C99:TC3 6.7.8, §10:

If an object that has automatic storage duration is not initialized explicitly, its value is indeterminate. If an object that has static storage duration is not initialized explicitly, then:

  • if it has pointer type, it is initialized to a null pointer;
  • if it has arithmetic type, it is initialized to (positive or unsigned) zero;
  • if it is an aggregate, every member is initialized (recursively) according to these rules;
  • if it is a union, the first named member is initialized (recursively) according to these rules.


Also, contrary to what others have written,

memset(array, 0, sizeof(array));

isn't guaranteed to result in null pointers. On some systems, a pointer with all its bits set to 0 might actually be valid. For mainstream systems, that's not the case, but with embedded systems, one never knows.

The safe way to set all entries to a null pointer is to either loop over the entries yourself and set them to NULL, or to use an uninitialized static array which you can memcpy() over the array you want to set to NULL.

Christoph
I'm curious: what is an example of a system for which pointer 0x00 is valid?
Crashworks
I've never seen one (even embedded ones), @Crashworks, but the standard says they're possible so it's a good idea to allow for it if there's a chance your software will ever run there. Pragmatism allows me to comfortably ignore that rule :-)
paxdiablo
@Crashworks: see http://www.lysator.liu.se/c/c-faq/c-1.html#1-14
Christoph
:-) A list of long-gone machines if ever I saw it. Still, I can see the potential for an embedded system with no memory management unit and ROM in the range 0xffff0000 thru 0xffffffff to use 0xffff0000 as NULL since it would prevent writing to NULL locations.
paxdiablo
@Pax: the page was last modified 1994, but I'd not be surprised if the contents were considerably older; as you already said: without virtual addresses, there are valid reasons why null pointers shouldn't be represented by the zero bit pattern
Christoph
+3  A: 

memset will do it in runtime.

static void* array[1024] = {0};

suggested by Pax will do it in compile time and it will increase the size of the executable.

For a library I believe memset is more appropriate.

kgiannakakis
+1  A: 

All you need is:


static void* array[1024];

because static variables are initialized to 0 anyways, so you don't really need to initiate this array, it will happen automatically.

Gal Goldman
A: 

but can i use realloc to re allocate additional space for array ??

aparna