tags:

views:

513

answers:

6

I have an array of structs. It's declared like this:

tableEntry [MAXSCOPE][MAXSIZE];

When the structs are created, C automatically initializes all the members to either 0 or null.

Let's say that I have given some values to the struct members of tableEntry[1][0], tableEntry[1][1], and tableEntry[1][2].

Now I want to reinitialize all struct members in tableEntry[1][x], where x can be any number from 0 up to MAXSIZE. How would I do that?

Essentially, I want to "delete" those structs. Later I might want to write to those structs and I don't want my new data to be contaminated by any old data that's already there, that's why I want to get rid of all the old data and reinitialize it like when it's first created.

+1  A: 

Why not simply

memset( &tableEntry1[1][x], 0, sizeof(tableEntry1[0][0]) );

Incidentally, the maximum value of x is MAXSIZE-1, not MAXSIZE.

Bill Forster
memset all bits to 0. This is not guaranteed to be the same as assigning zero, for example for floating point or pointer types.
Lars Wirzenius
+4  A: 

No, C only automatically initializes all the members to 0 when your variable has static storage, otherwise you have to write:

struct TableEntry tableEntry [MAXSCOPE][MAXSIZE] = {0};

If your tableEntry is a global variable or declared static inside a function, then you don't need the = {0} part.

Then you can use memset to reinitialize some of the entries afterwards:

memset(tableEntry[1], 0, sizeof(struct TableEntry) * MAXSIZE);

will reinitialize tableEntry[1][0] ... tableEntry[1][MAXSIZE - 1] to 0.

Gregory Pakosz
C **does** guarantee zero-initialization of variables with static lifetime (global and static variables).
Lars Wirzenius
He's very likely using global storage, though, but I can't be sure. Either way, we're all just trying to help the OP sort out his troubles.
Chris Lutz
@both agreed, I edited the answer, thank you
Gregory Pakosz
next time, please explain the downvote(s) so that I can improve, thx!
Gregory Pakosz
I didn't downvote, but all bytes 0 may or may not represent zero for some types. In particular, floating point and pointer values can have 0 as not all bytes 0.
Alok
i don't really see how
Gregory Pakosz
@Gregory: because the C standard allows this. There are systems where memory location `0` has useful code. On such systems, `NULL` is not all bits `0`. Similarly, there are floating point representations where all bits 0 is not floating-point 0.
Alok
+1  A: 

You can use memset to set all bits to zero.

#include <string.h>

    memset(&tableEntry[1][0], 0, sizeof tableEntry[1][0]);
    memset(&tableEntry[1][1], 0, sizeof tableEntry[1][1]);
    memset(&tableEntry[1][2], 0, sizeof tableEntry[1][2]);

    /* if the elements are contiguous in memory,
     * you can set more than 1 in a single statement */
    memset(&tableEntry[1][0], 0, 3 * sizeof tableEntry[1][0]); /* zeroes ...[1][0], [1][1], and [1][2] */

    /* to set all of a sub array */
    memset(tableEntry[1], 0, sizeof tableEntry[1]);

Maybe setting all bits to 0 might not be what you want. If that's the case, you need to "delete" the elements one-by-one.

pmg
+1 for beating to me to the contiguous memory punch.
Chris Lutz
+1  A: 

If you want to reset a whole row, ignore these people with for loops. You can do a row in one call to memset(), because rows are consecutive in memory:

memset(&tableEntry[1][0], 0, sizeof(tableEntry[0]));

sizeof(tableEntry[0]) will be MAXSIZE * sizeof(type), so this will reset all the elements, which, being the bottom level of an array, have to be contiguous in memory. (Anyone saying otherwise is arguing academics, because the OP has posted previous questions about this, and I believe tableEntry is just a two-dimensional array allocated on the stack.)

Chris Lutz
`memset(tableEntry[1], 0, sizeof tableEntry[1])` is completely equivalent, and looks a bit better to my eye anyway.
caf
Chris Lutz
+1  A: 

In addition to the memset suggestions, I offer this:

/* Global variables are initialized to zero by compiler. */
struct foo TableEntry[MAXSCOPE][MAXSIZE];
struct foo zero;

/* Initialize yourself. */
for (int i = 0; i < MAXSIZE; ++i)
    TableEntry[1][i] = zero;

If you wish to optimize, you can in your build script see if memset does the same thing as assigning the zero struct and optionally use memset instead. You might want to profile things to see if it matters, though.

Lars Wirzenius
"does the same thing as **assing** the `zero` struct" While I understand your abbreviation, it's still really funny.
Chris Lutz
Oh my fingers, how you embarrass me. Fixing...
Lars Wirzenius
If it's not too embarrassing for you, I'm totally leaving the comment there.
Chris Lutz
No, that's perfectly fine. :)
Lars Wirzenius
A: 

All the answers with memset don't do the Right Thing always. This is because all-bits-zero may not represent zero for floating-point numbers and pointers. You can do this though:

static struct T zeroed; /* static, therefore every member
                           is initialized to an appropriate
                           'zero' value */
size_t i;
for (i=0; i < MAXSIZE; ++i)
    tableEntry[1][i] = zeroed;
Alok
NULL pointer is zero. And at least in IEEE floating point numbers, zero value is represented by all bits zero. Static storage may or may not be initialized to zero, depending on compiler options. But if it is initialized, that is done by filling the memory with zero bytes.
PauliL
@PauliL: If you assign the value 0 to a pointer (p=0;) then the pointer is effectively set to NULL. But the representation of a NULL-pointer is not required to be all bits 0. In fact I had an old DOS compiler where a NULL pointer was all bits 1.
Secure