Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > memset

Reply
Thread Tools

memset

 
 
Eric Sosman
Guest
Posts: n/a
 
      01-28-2008
http://www.velocityreviews.com/forums/(E-Mail Removed)lid wrote:
> In article <(E-Mail Removed)>,
> Eric Sosman <(E-Mail Removed)> wrote:
>
>> For very large arrays that need to be filled/refilled very
>> many times, here's a function I cooked up long ago:
>>
>> #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) {
>> memcpy (pdest, pfrom, sfrom);
>> pfrom = pdest;
>> pdest = (char*)pdest + sfrom;
>> sdest -= sfrom;
>>
>> while (sdest > sfrom) {
>> memcpy (pdest, pfrom, sfrom);
>> pdest = (char*)pdest + sfrom;
>> sdest -= sfrom;
>> sfrom += sfrom;
>> }
>> }
>>
>> memcpy (pdest, pfrom, sdest);
>> }
>>
>> <off-topic> At first glance and even at second glance, this looks
>> like a cache-killer. But on the platforms I've tested it doesn't
>> appear to suffer from cache-aliasing problems. It seems likely
>> that memcpy() on these platforms is implemented cleverly (and non-
>> portably) to dodge such issues. </off-topic>

>
> How 'bout something like this?
> --------
> void fillmem(void *pdest,size_t sdest,const void *pfrom,size_t sfrom)
> {
> if(sdest <= sfrom)
> {
> memcpy(pdest,pfrom,sdest);
> return;
> }
> /*Make the first copy of from*/
> memcpy(pdest,pfrom,sfrom);
> /*Now make the rest of the copies from the last copy
> we made
> */
> memmove((char *)pdest + sfrom,pdest,sdest-sfrom);
> }


memmove() doesn't "smear" the data the way this needs it
to. You'll end up with two copies of the fill pattern followed
by a big blob of whatever was in the destination beforehand,
slid rightwards by sfrom bytes.

7.21.2.2p2: "[...] Copying takes place as if the n
characters from the object pointed to by s2 are first
copied into a temporary array of n characters that does
not overlap the objects pointed to by s1 and s2, and
then the n characters from the temporary array are copied
into the object pointed to by s1."

> (Interestingly, I invented this independently about a week before
> reading a description in comp.arch of the same technique being used in
> a system older than I am.)


This technique for "smearing" has been around since the days
of the dawn; I first encountered it in 1966 as a clear-core
program that was one instruction long. But that's not what
memmove() does.

--
Eric Sosman
(E-Mail Removed)lid
 
Reply With Quote
 
 
 
 
dj3vande@csclub.uwaterloo.ca.invalid
Guest
Posts: n/a
 
      01-28-2008
In article <(E-Mail Removed)>,
Eric Sosman <(E-Mail Removed)> wrote:

> memmove() doesn't "smear" the data the way this needs it
>to. You'll end up with two copies of the fill pattern followed
>by a big blob of whatever was in the destination beforehand,
>slid rightwards by sfrom bytes.
>
> 7.21.2.2p2: "[...] Copying takes place as if the n
> characters from the object pointed to by s2 are first
> copied into a temporary array of n characters that does
> not overlap the objects pointed to by s1 and s2, and
> then the n characters from the temporary array are copied
> into the object pointed to by s1."


Hmmmmmmm....

I could've sworn that said something different last time I read it,
which must have been too many lost neurons ago.
I suppose it's a Good Thing you pointed that out before I got around to
finishing the project I was planning to use it in, then.


> This technique for "smearing" has been around since the days
>of the dawn; I first encountered it in 1966 as a clear-core
>program that was one instruction long. But that's not what
>memmove() does.


Is there a reason (well, a reason behind history, which is probably the
currently-live reason) why memmove does a non-destructive copy instead
of smearing? It seems, to my limited imagination, that smearing would
be a lot more useful.


dave

--
Dave Vandervies dj3vande at eskimo dot com
Effectively, Microsoft creates good programming the same way that sand
grains create pearls - through irritating someone else. And Microsoft has
a lot of sand. --SteveD in the scary devil monastery
 
Reply With Quote
 
 
 
 
Billy Bong
Guest
Posts: n/a
 
      01-29-2008
On Sat, 26 Jan 2008 15:31:41 -0600, Jack Klein wrote:

> On Sat, 26 Jan 2008 13:02:39 -0800 (PST), Gaijinco <(E-Mail Removed)>
> wrote in comp.lang.c:
>
>> I'm having a headache using memset()
>>
>> Given:
>>
>> int v[1000000];
>> memset((void*)v, 1, sizeof(v));

>
> No need for the cast to void pointer here, the conversion is automatic.
> But do make sure to include <string.h>. Also there is no need for the
> parentheses abound the 'v' as an operand to the sizeof operator, as 'v'
> is an object, not a type.
>
>> Can I be 100% positive than v[i] = 1 for i > 0, or there is something
>> else I have to do?.

>
> No you can't, and on most implementations it will not be. memset() will
> place the value 1 into every byte that makes up the array, and there are
> 1,000,000 times sizeof (int) bytes in the array.
>
> There are a few implementations, mostly digital signal processors, where
> CHAR_BIT is 16 and char and int have the same size and representation,
> where every int in the array will be set to the value 1.
>
> But on most platforms, especially anything in a desktop computer, you
> won't get that value.
>
> On old 16-bit implementations for MS-DOS, each int in the array will
> wind up with the value 257.
>
> On 32-bit Windows, Macintosh, or Linux platforms using x86 processors,
> each int in the array will have the value 16843009.
>
> On 64-bit operating systems using x86, the result will be
> 72340172838076673.
>
>> In various computers that I have tried it seems that the only value I
>> can copy to a range with memset() that works is 0.

>
> It works for a value of 0 because memset() with a value of 0 will set
> every bit in every byte to all bits 0. C guarantees that any integer
> type with a value of all bits 0 has the value 0. This is not guaranteed
> for floating point types or pointers.
>
> As to how to do it, you need to use a loop:
>
> #define ARRAY_SIZE 1000000
>
> int v [ARRAY_SIZE];
>
> size_t index;
>
> for (index = 0; index < ARRAY_SIZE]; ++index) {
> v [index] = 1;
> }


Sans the extraneous ']' character after ARRAY_SIZE in the above for loop
(which requires a compiler diagnostic, and which is obviously a typo by
Mr. Klein), this is the way to do it.

If you want to initialize an array and do it in a portable, Standard C
compliant way, then using a for loop as above will guarantee this. Using
memset will not always guarantee this.

This should be a part of everyone's coding standard:

In code, always use a for loop (instead of, for example, memset) to
initialize an array.

--
Billy

 
Reply With Quote
 
Richard Heathfield
Guest
Posts: n/a
 
      01-29-2008
[comp.std.c added, no followups set - can we keep this in both groups
please? Ta.]

Billy Bong said:

> On Sat, 26 Jan 2008 15:31:41 -0600, Jack Klein wrote:
>

<snip>

>> int v [ARRAY_SIZE];
>>
>> size_t index;
>>
>> for (index = 0; index < ARRAY_SIZE]; ++index) {
>> v [index] = 1;
>> }

>
> Sans the extraneous ']' character after ARRAY_SIZE in the above for loop
> (which requires a compiler diagnostic, and which is obviously a typo by
> Mr. Klein), this is the way to do it.
>
> If you want to initialize an array and do it in a portable, Standard C
> compliant way, then using a for loop as above will guarantee this. Using
> memset will not always guarantee this.


....unless the array is of objects with integer type and the value you wish
to write into the array is 0, as we are assured from time to time by
various ISO members. This cannot AFAIK be deduced directly from the
Standard, though. Did it ever make it as far a TC?

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
 
Reply With Quote
 
Eric Sosman
Guest
Posts: n/a
 
      01-29-2008
(E-Mail Removed)lid wrote:
> [...]
> Is there a reason (well, a reason behind history, which is probably the
> currently-live reason) why memmove does a non-destructive copy instead
> of smearing? It seems, to my limited imagination, that smearing would
> be a lot more useful.


memmove() copies N bytes from source to destination.
The bytes that land in the destination are duplicates of
those that were in the source prior to the operation. So,
for example, you can use it to open a gap in an array:

memmove (array+C+i, array+C, (N-C-i) * sizeof array[0]);

.... or to close a gap:

memmove (array+C, array+C+i, (N-C-i) * sizeof array[0]);

With the "smearing" semantics -- which we've seen can be
obtained by other means -- these wouldn't work.

Look at it this way: memmove() and memcpy() "do the same
thing," except that the former promises to behave nicely even
when source and destination overlap, while the latter doesn't.

--
Eric Sosman
(E-Mail Removed)lid
 
Reply With Quote
 
Spoon
Guest
Posts: n/a
 
      01-29-2008
Richard Heathfield wrote:

> [comp.std.c added, no followups set - can we keep this in both
> groups please? Ta.]


I don't think you added comp.std.c
 
Reply With Quote
 
Army1987
Guest
Posts: n/a
 
      01-29-2008
Richard Heathfield wrote:

> ...unless the array is of objects with integer type and the value you wish
> to write into the array is 0, as we are assured from time to time by
> various ISO members. This cannot AFAIK be deduced directly from the
> Standard, though. Did it ever make it as far a TC?


n1256 in 6.2.6.2p5 has: A valid (non-trap) object representation
of a signed integer type where the sign bit is zero is a valid object representation of the
corresponding unsigned type, and shall represent the same value. For any integer type,
the object representation where all the bits are zero shall be a representation of the value
zero in that type.

There are change bars beside the last sentence.
See http://www.open-std.org/jtc1/sc22/wg...ocs/dr_263.htm

--
Army1987 (Replace "NOSPAM" with "email")
 
Reply With Quote
 
Richard Heathfield
Guest
Posts: n/a
 
      01-29-2008
Spoon said:

> Richard Heathfield wrote:
>
>> [comp.std.c added, no followups set - can we keep this in both
>> groups please? Ta.]

>
> I don't think you added comp.std.c


Oh FOO BAR BAZ, you're right. Oh well...


--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
 
Reply With Quote
 
Richard Heathfield
Guest
Posts: n/a
 
      01-29-2008
Army1987 said:

> Richard Heathfield wrote:
>
>> ...unless the array is of objects with integer type and the value you
>> wish to write into the array is 0, as we are assured from time to time
>> by various ISO members. This cannot AFAIK be deduced directly from the
>> Standard, though. Did it ever make it as far a TC?

>
> n1256 in 6.2.6.2p5 has: A valid (non-trap) object representation
> of a signed integer type where the sign bit is zero is a valid object
> representation of the corresponding unsigned type, and shall represent
> the same value. For any integer type, the object representation where
> all the bits are zero shall be a representation of the value zero in
> that type.
>
> There are change bars beside the last sentence.
> See http://www.open-std.org/jtc1/sc22/wg...ocs/dr_263.htm


Well, that answers that. Thanks, Army1987.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
 
Reply With Quote
 
dj3vande@csclub.uwaterloo.ca.invalid
Guest
Posts: n/a
 
      01-29-2008
In article <(E-Mail Removed)>,
Eric Sosman <(E-Mail Removed)> wrote:

> Look at it this way: memmove() and memcpy() "do the same
>thing," except that the former promises to behave nicely even
>when source and destination overlap, while the latter doesn't.


I think the source of my confusion may have been combining this with
understanding the behavior of memcpy as "copies as if by a simple
byte-copying loop" rather than "makes a duplicate copy".

The two behaviors are equivalent for non-overlapping chunks of memory,
but a simple byte-copying loop with (char*)src < (char*)dest <
(char*)src+size would do a smearing copy, while "making a duplicate
copy" excludes smearing by definition.


(It should be obvious by now that I rarely (never, as far as I can
remember) have to copy data between overlapping chunks of memory.)


dave

--
Dave Vandervies dj3vande at eskimo dot com

I really really wish Larry Wall was a native speaker of some language that
actually had rules. --Peter da Silva in the Scary Devil Monastery
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Re: "memset" vs "= {0}"...Are they equivalent if your initializing variables? C++ 1 09-23-2004 02:03 PM
Re: "memset" vs "= {0}"...Are they equivalent if your initializing variables? C++ 0 09-23-2004 01:28 PM
"memset" vs "= {0}"...Are they equivalent if your initializing variables? Nollie@runtime.com C++ 17 09-22-2004 06:06 PM
memset vs fill and iterators vs pointers Joe C C++ 5 08-24-2004 11:51 AM
2 questions: speed of memset() and pointer to multi-arrays k-man C++ 4 12-18-2003 08:52 PM



Advertisments