Elegant way to clear a struct ?

N

Nils Emil P. Larsen

Hello

I have a pointer to a struct or an array of structs and I know the
lenght of the struct or array of structs.

I need a elegant way to clear it with zeroes.

Is it legal just to do something like

Mystruct *mystruct; // Mystruct is a typedef

for (i=0; i < sizeof(Mystruct); i++)
*(mystruct+i) = 0;

or do I have to clear each individual members ?

Thank you
Nils Emil P. Larsen

H

Hallvard B Furuseth

Nils said:
I have a pointer to a struct or an array of structs and I know the
lenght of the struct or array of structs.

I need a elegant way to clear it with zeroes.

Mystruct *mystruct; // Mystruct is a typedef

If the struct contains nothing but integer (and character) elements,
you can just do
memset(mystruct, 0, array_length * sizeof(Mystruct))
Otherwise, use
const Mystruct null_mystruct; /* will be initialized with nulls */
for (i = 0; i < array_length; i++)
mystruct = null_mystruct;

BTW, note that ANSI C (or ISO C89) do not accept '//' comments. Only
C++ and C99 do.

R

Richard Heathfield

Nils said:
Hello

I have a pointer to a struct or an array of structs and I know the
lenght of the struct or array of structs.

I need a elegant way to clear it with zeroes.

Is it legal just to do something like

Mystruct *mystruct; // Mystruct is a typedef

for (i=0; i < sizeof(Mystruct); i++)
*(mystruct+i) = 0;

That looks rather confused to me. Very confused, in fact.

Given that mystruct points to an array of N Mystruct objects, you can do
this:

Mystruct blank = {0};

for(i = 0; i < N; i++)
{
mystruct = blank;
}

H

Hallvard B Furuseth

I said:
const Mystruct null_mystruct; /* will be initialized with nulls */

Sorry, that should be 'static const null_mystruct', unless
null_mystruct has file scope.

K

Kevin Easton

Hallvard B Furuseth said:
If the struct contains nothing but integer (and character) elements,
you can just do
memset(mystruct, 0, array_length * sizeof(Mystruct))
Otherwise, use
const Mystruct null_mystruct; /* will be initialized with nulls */

What basis do you have for that comment? Did you perhaps mean either:

const Mystruct null_mystruct = { 0 };

or

static const Mystruct null_mystruct;

?
for (i = 0; i < array_length; i++)
mystruct = null_mystruct;

- Kevin.

K

Kevin Easton

Hallvard B Furuseth said:
Sorry, that should be 'static const null_mystruct', unless
null_mystruct has file scope.

What use is an int variable called "null_mystruct" in this context?

- Kevin.

E

Emmanuel Delahaye

In 'comp.lang.c' said:
I have a pointer to a struct or an array of structs and I know the
lenght of the struct or array of structs.

'length'. In fact, you mean 'size'.
I need a elegant way to clear it with zeroes.

Mystruct *mystruct = malloc (sizeof *mystruct);

if (mystruct)
{
static const Mystruct z = {0};

*mystruct = z;
}
Is it legal just to do something like

Mystruct *mystruct; // Mystruct is a typedef

for (i=0; i < sizeof(Mystruct); i++)
*(mystruct+i) = 0;

or
mystruct = 0;

Assuming 'mystruct' was initialized with an the address of an (allocated)
bloc of data, none of the two forms is legal.

M

Martin Ambuhl

Hello

I have a pointer to a struct or an array of structs and I know the
lenght of the struct or array of structs.

I need a elegant way to clear it with zeroes.

Is it legal just to do something like

Mystruct *mystruct; // Mystruct is a typedef

for (i=0; i < sizeof(Mystruct); i++)
*(mystruct+i) = 0;

This won't do it, since *(mystruct+i) is mystruct.
or do I have to clear each individual members ?

Depending on the types of members a Mystruct has, memset() might do it
for you.

S

Simon Biber

Nils Emil P. Larsen said:
I have a pointer to a struct or an array of structs and
I know the lenght of the struct or array of structs.

I need a elegant way to clear it with zeroes.

Is it legal just to do something like

Mystruct *mystruct; // Mystruct is a typedef

for (i=0; i < sizeof(Mystruct); i++)
*(mystruct+i) = 0;

When you add i to mystruct you are constructing another
pointer to Mystruct, which points to the i-th successive
Mystruct after the one that mystruct actually points to.

See how confusing it is to have variables and types with
names differentiated only by case? That's not a good idea.

So, what does sizeof(Mystruct) have to do with successive
Mystructs after the one pointed to by mystruct? If you
wanted to address each *byte* of the structure, you have
to cast the pointer to (unsigned char *). You would be
in essence just recreating what is done for you by memset.
But that is not a portable way to zero out most types.

This looks to me like a place where C99's compound literals
would be useful. Example code follows.

#include <stdlib.h>

typedef struct {int a; char *p;} Mystruct;

int main(void)
{
Mystruct *foo = malloc(sizeof *foo);
if(foo)
{
*foo = (Mystruct){0};
}

Mystruct bar[42];
for(size_t i = 0; i < sizeof bar / sizeof *bar; i++)
{
bar = (Mystruct){0};
}

return 0;
}

This code was tested on GCC 3.2 with command line
gcc -std=c99 -pedantic -Wall -W -O2 zerostruct.c -o zerostruct

R

Richard Heathfield

Ravi said:
Hallvard B Furuseth said:
Sorry, that should be 'static const null_mystruct', unless
null_mystruct has file scope.

What if i have a struct like this
typedef struct str
{
int i;
char c[20]
char *temp;
}my_str;

int main ()
{
my_str st;
static const my_str zero;

st.c = 'a';
st.temp = malloc ( 10 * sizeof char );

Either drop sizeof char altogether, or replace it with sizeof *st.temp, or
at least put () around char.
/* Now if i say as follows */
st = zero;

/*will it free the alloc mem for temp
No.

and then assign zero or how does it
work*/

It will leak the memory you assigned. Solution: free the memory first.

<snip>

H

Hallvard B Furuseth

That statement should either be at file scope, or it should be
static const Mystruct null_mystruct;

This time I got it right, I think
Mystruct da_azzerare;

da_azzerare = null_mystruct;

That's fine.
*( Mystruct *) &da_azzerare = *( Mystruct *) &null_struct;

Oh my gosh. You could, but don't. BTW, it should have been
*( const Mystruct *) &null_struct;
since you should not cast away const when you don't need to.

K

Kevin Easton

bd said:
That's implicit in static and file scope variables.

It was neither static nor file scope (because the next line was a
statement, which can't appear at file scope).

- Kevin.