Clearing an array

M

Michael

Hello Newsgroup,

I have a 2D-array of doubles. Can I use memset
to set all elements to zero like
memset ( arrayname, 0, "arraysize" )
or is this not general allowed?


Thanks
Michael
 
D

David Resnick

Michael said:
Hello Newsgroup,

I have a 2D-array of doubles. Can I use memset
to set all elements to zero like
memset ( arrayname, 0, "arraysize" )
or is this not general allowed?


Thanks
Michael

This is in the FAQ though you might not find it where you'd
expect:

http://www.eskimo.com/~scs/C-faq/q7.31.html

The answer there is "no", I guess that is the official portable
answer.

The longer answer is it will almost certainly work
anywhere you will do it. If you google in comp.lang.c
for
float all bits zero
You will find interesting discussion on the matter.

-David
 
J

Jens.Toerring

Michael said:
I have a 2D-array of doubles. Can I use memset
to set all elements to zero like
memset ( arrayname, 0, "arraysize" )
or is this not general allowed?

No, because the third element of memset() is an integer (of type
size_t) and not a char pointer - unless you meant '"arraysize"'
to stand for something like 'sizeof arrayname'.

But then the problem is that the floating point value 0.0 is not
necessarily represented by all bits set to 0 (even though it may
on your machine). So you have to loop over all elements and set
them to 0.0 individually, at least if you want your program to be
portable.
Regards, Jens
 
B

Ben Pfaff

Michael said:
I have a 2D-array of doubles. Can I use memset
to set all elements to zero like
memset ( arrayname, 0, "arraysize" )
or is this not general allowed?

No, this is not guaranteed to set the array elements to
floating-point value 0.
 
F

Flash Gordon

Michael said:
Hello Newsgroup,

I have a 2D-array of doubles. Can I use memset
to set all elements to zero like
memset ( arrayname, 0, "arraysize" )
or is this not general allowed?

Short answer, it's not portable.

Using memset will set all bits to zero, however there is no guarantee
that all bits 0 is a valid double representation of 0. It could even be
a trap and if evaluated cause your program to abort.
 
M

Malcolm

Michael said:
I have a 2D-array of doubles. Can I use memset
to set all elements to zero like
memset ( arrayname, 0, "arraysize" )
or is this not general allowed?
No. In general it works, which creates a huge problem with "portable enough"
programs which appear to work fine on most hardware, but might give wrong
results many years later when the original programmers have moved on and no
one can maintain the code.
 
E

Eric Sosman

Malcolm said:
No. In general it works, which creates a huge problem with "portable enough"
programs which appear to work fine on most hardware, but might give wrong
results many years later when the original programmers have moved on and no
one can maintain the code.

Some time ago I wrote this function to fill a region of
memory with copies of a block of arbitrary size:

#include <string.h>

void
fillmem(void *pdest, size_t sdest, const void *pfrom, size_t sfrom)
/*
* Fills the `sdest' bytes starting at `pdest' with copies of the
* `sfrom' bytes starting at `pfrom'. The final copy will be partial
* if `sfrom' does not divide `sdest'.
*/
{
if (sdest > sfrom) {
/* Put one copy of the source pattern at the start of
* the destination.
*/
memcpy (pdest, pfrom, sfrom);
pfrom = pdest;
pdest = (char*)pdest + sfrom;
sdest -= sfrom;

/* Copy data from the beginning of the destination to
* the end, each iteration doubling the amount copied.
*/
while (sdest > sfrom) {
memcpy (pdest, pfrom, sfrom);
pdest = (char*)pdest + sfrom;
sdest -= sfrom;
sfrom += sfrom;
}
}

/* Fill the final (or only) piece of the destination.
*/
memcpy (pdest, pfrom, sdest);
}

This could be used as a portable way to initialize an
array of `double's to zero -- or to 1.0, or to alternating
+42.0 and -42.0, or whatever.

<off-topic>

At first glance this function looks like it might be a
cache-killer, as those successively-doubling memcpy() calls
keep flooding the same set of cache lines. On the three or
four machines where I've tested it, though, I haven't seen
evidence of cache thrashing. Perhaps those systems' memcpy()
implementations use special memory-to-memory data paths that
avoid flooding the cache -- I don't really know, and haven't
cared enough to study it closely. If anyone wants to research
this at greater depth -- or even just report that it does or
doesn't kill the cache on System X -- I wouldn't mind hearing
about your experiences.

</off-topic>
 
C

CBFalconer

Flash said:
Short answer, it's not portable.

Using memset will set all bits to zero, however there is no
guarantee that all bits 0 is a valid double representation of 0.
It could even be a trap and if evaluated cause your program to
abort.

While this is perfectly accurate, I believe that it is one of the
changes being made for the interim revision of C99 (to C05 or so).
I vaguely remember reading that the standards group had been unable
to find a system where all bits zero did not represent a zero
double, and that they thus could add the requirement. I am quite
prepared to be corrected.

Note that this cavalier attitude DOES NOT apply to NULL pointers.

--
Some informative links:
http://www.geocities.com/nnqweb/
http://www.catb.org/~esr/faqs/smart-questions.html
http://www.caliburn.nl/topposting.html
http://www.netmeister.org/news/learn2quote.html
 
K

Keith Thompson

CBFalconer said:
While this is perfectly accurate, I believe that it is one of the
changes being made for the interim revision of C99 (to C05 or so).
I vaguely remember reading that the standards group had been unable
to find a system where all bits zero did not represent a zero
double, and that they thus could add the requirement. I am quite
prepared to be corrected.

I thought the recently added requirement was that all-bits-zero is a
valid representation of 0 for all integer types. The standard leaves
open the possibility that all-bits-zero could be a trap representation
for any integer type bigger than char.

I don't believe they've changed anything for floating-point types.

I too am quite prepared to be corrected.
 
J

Jack Klein

While this is perfectly accurate, I believe that it is one of the
changes being made for the interim revision of C99 (to C05 or so).
I vaguely remember reading that the standards group had been unable
to find a system where all bits zero did not represent a zero
double, and that they thus could add the requirement. I am quite
prepared to be corrected.

Note that this cavalier attitude DOES NOT apply to NULL pointers.

Keith is correct. The C standard is adding a specification that all
bits 0 is a valid representation for the value 0 in all integer types.
No such requirement is placed on floating point types. Like pointers,
the C standard leaves the internal representation of floating point
types completely opaque and implementation-defined.
 
P

Peter Nilsson

Jack said:
Keith is correct. The C standard is adding a specification that all
bits 0 is a valid representation for the value 0 in all integer
types.

As I read things, DR263 (published in TC2) is supposedly just inserting
wording which clarifies what the committee's intent was all along (that
all bits zero represents zero for integer types.)
 
T

Thomas Matthews

Michael said:
Hello Newsgroup,

I have a 2D-array of doubles. Can I use memset
to set all elements to zero like
memset ( arrayname, 0, "arraysize" )
or is this not general allowed?


Thanks
Michael

One method is to have a small set of doubles
which are set to 0.0 and copying them into
the array. This works for single dimension
arrays and larger areas provided that the
memory is contiguous.

void fill_doubles(double * p_array,
size_t quantity)
{
const unsigned int DOUBLES_PER_BLOCK = 4;
double * p_temp;
size_t remaining_qty = quantity;

p_temp = malloc(DOUBLES_PER_BLOCK * sizeof(double));
if (p_temp)
{
unsigned int i;
for (i = 0; i < DOUBLES_PER_BLOCK; ++i)
{
p_temp = 0.0;
}
while (remaining_qty > DOUBLES_PER_BLOCK)
{
memcpy(p_array, p_temp,
DOUBLES_PER_BLOCK * sizeof(double))
p_array += DOUBLES_PER_BLOCK;
remaining_qty -= DOUBLES_PER_BLOCK;
}
free(p_temp);
}
while (remaining_qty > 0)
{
*p_array++ = 0.0;
}
return;
}

Alter the DOUBLES_PER_BLOCK to suit your needs.

--
Thomas Matthews

C++ newsgroup welcome message:
http://www.slack.net/~shiva/welcome.txt
C++ Faq: http://www.parashift.com/c++-faq-lite
C Faq: http://www.eskimo.com/~scs/c-faq/top.html
alt.comp.lang.learn.c-c++ faq:
http://www.comeaucomputing.com/learn/faq/
Other sites:
http://www.josuttis.com -- C++ STL Library book
http://www.sgi.com/tech/stl -- Standard Template Library
 
M

Michael

Michael said:
Hello Newsgroup,

I have a 2D-array of doubles. Can I use memset
to set all elements to zero like
memset ( arrayname, 0, "arraysize" )
or is this not general allowed?
Hi Newsgroup,

thanks to all of you for answering my
question and providing hints. I'll look for
a more portabe way.

Bye,
Michael
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,164
Messages
2,570,897
Members
47,439
Latest member
shasuze

Latest Threads

Top