Discussion:
memset question!
(too old to reply)
Robby
2009-09-10 01:14:01 UTC
Permalink
Hello,

I nevery really use memset() in my code , I usually innitialize all my array
values through a for-loop. But for curiosity purpose, why does memset work
only with char arrays?

For example, the following works:
=========================
int main()
{
int i;
char t;
char buf[100];

memset(buf, 'X', 100);

for(i=0; i<100; i++)
t = buf[i]; // t retrieves the right innitialized values from buf!
return 0;
}
===================================

But this doesn't ???
==================================
int main()
{
int i;
int t;
int h[100];

memset(h,11,100);

for(i=0; i<100; i++)
t = h[i]; // t does not retrieve the right innitialized values from h !

return 0;
}
==================================

The actual definition of memset is:

"The most common use of memset() is to initialize a region of memory to some
value."

So isn't an array of integers a valid region of memory that can be set by
memset?

Just asking!

PS Thankyou for all replies!
--
Best regards
Roberto
Nathan Mates
2009-09-10 01:40:16 UTC
Permalink
Post by Robby
I nevery really use memset() in my code , I usually innitialize all my array
values through a for-loop. But for curiosity purpose, why does memset work
only with char arrays?
Short summary: because you don't know how powerful & useful
sizeof() is.
Post by Robby
char buf[100];
memset(buf, 'X', 100);
This works, because buf is exactly 100 bytes long. But, random
numbers like 100 in your code are BAD. If you must use 100, do it in
as few places as possible:

char buf[100];
memset(buf, 'X', sizeof(buf));

That has the compiler figure out how large buf is, in bytes,
and pass that to memset. sizeof() is done at *compile* time, not
run time, so there's no speed penalty for doing this.
Post by Robby
int h[100];
memset(h,11,100);
That doesn't work, because ints are larger than bytes. But,
you only cleared the first 100 *bytes* of the h array. If you switch
to sizeof, it'll work!

int h[100];
memset(h, 11, sizeof(h));

That'll fill all 400 *bytes* of the h array. memset's middle
parameter is also a *byte* fill pattern. So, filling an integer with
11, like above will fill it with hex 0x0B0B0B0B, or decimal
185273099. For that reason, memset's middle parameter is best passed
in as 0, 0xFF, or some other low-level known value.

Nathan Mates

--
<*> Nathan Mates - personal webpage http://www.visi.com/~nathan/
# Programmer at Pandemic Studios -- http://www.pandemicstudios.com/
# NOT speaking for Pandemic Studios. "Care not what the neighbors
# think. What are the facts, and to how many decimal places?" -R.A. Heinlein
Robby
2009-09-10 15:36:03 UTC
Permalink
Hello Nathan and Vincent,
Post by Nathan Mates
That'll fill all 400 *bytes* of the h array. memset's middle
parameter is also a *byte* fill pattern. So, filling an integer with
11, like above will fill it with hex 0x0B0B0B0B, or decimal
185273099. For that reason, memset's middle parameter is best passed
in as 0, 0xFF, or some other low-level known value.
I was wondering where that "185273099" was coming from.

So now I understand why everyone was saying that memset is best used with 0.
Or as you pointed out 0xFF (or 255 decimal)!

Thanks guys!
--
Best regards
Roberto
Post by Nathan Mates
Post by Robby
I nevery really use memset() in my code , I usually innitialize all my array
values through a for-loop. But for curiosity purpose, why does memset work
only with char arrays?
Short summary: because you don't know how powerful & useful
sizeof() is.
Post by Robby
char buf[100];
memset(buf, 'X', 100);
This works, because buf is exactly 100 bytes long. But, random
numbers like 100 in your code are BAD. If you must use 100, do it in
char buf[100];
memset(buf, 'X', sizeof(buf));
That has the compiler figure out how large buf is, in bytes,
and pass that to memset. sizeof() is done at *compile* time, not
run time, so there's no speed penalty for doing this.
Post by Robby
int h[100];
memset(h,11,100);
That doesn't work, because ints are larger than bytes. But,
you only cleared the first 100 *bytes* of the h array. If you switch
to sizeof, it'll work!
int h[100];
memset(h, 11, sizeof(h));
That'll fill all 400 *bytes* of the h array. memset's middle
parameter is also a *byte* fill pattern. So, filling an integer with
11, like above will fill it with hex 0x0B0B0B0B, or decimal
185273099. For that reason, memset's middle parameter is best passed
in as 0, 0xFF, or some other low-level known value.
Nathan Mates
--
<*> Nathan Mates - personal webpage http://www.visi.com/~nathan/
# Programmer at Pandemic Studios -- http://www.pandemicstudios.com/
# NOT speaking for Pandemic Studios. "Care not what the neighbors
# think. What are the facts, and to how many decimal places?" -R.A. Heinlein
jayachandran kamaraj
2009-09-10 18:59:52 UTC
Permalink
Post by Robby
Hello Nathan and Vincent,
Post by Nathan Mates
That'll fill all 400 *bytes* of the h array. memset's middle
parameter is also a *byte* fill pattern. So, filling an integer with
11, like above will fill it with hex 0x0B0B0B0B, or decimal
185273099. For that reason, memset's middle parameter is best passed
in as 0, 0xFF, or some other low-level known value.
I was wondering where that "185273099" was coming from.
So now I understand why everyone was saying that memset is best used with 0.
Or as you pointed out 0xFF (or 255 decimal)!
Thanks guys!
--
Best regards
Roberto
Post by Nathan Mates
Post by Robby
I nevery really use memset() in my code , I usually innitialize all my array
values through a for-loop. But for curiosity purpose, why does memset work
only with char arrays?
   Short summary: because you don't know how powerful & useful
sizeof() is.
Post by Robby
char buf[100];
memset(buf, 'X', 100);
   This works, because buf is exactly 100 bytes long. But, random
numbers like 100 in your code are BAD. If you must use 100, do it in
char buf[100];
memset(buf, 'X', sizeof(buf));
   That has the compiler figure out how large buf is, in bytes,
and pass that to memset. sizeof() is done at *compile* time, not
run time, so there's no speed penalty for doing this.
Post by Robby
int h[100];
memset(h,11,100);
   That doesn't work, because ints are larger than bytes. But,
you only cleared the first 100 *bytes* of the h array. If you switch
to sizeof, it'll work!
int h[100];
memset(h, 11, sizeof(h));
   That'll fill all 400 *bytes* of the h array. memset's middle
parameter is also a *byte* fill pattern. So, filling an integer with
11, like above will fill it with hex 0x0B0B0B0B, or decimal
185273099. For that reason, memset's middle parameter is best passed
in as 0, 0xFF, or some other low-level known value.
Nathan Mates
--
<*> Nathan Mates - personal webpagehttp://www.visi.com/~nathan/ 
# Programmer at Pandemic Studios --http://www.pandemicstudios.com/
# NOT speaking for Pandemic Studios. "Care not what the neighbors
# think. What are the facts, and to how many decimal places?" -R.A. Heinlein
memset(h, 11, sizeof(int)*100)

gives you 0x0b0b0b0b because int is 4 bytes long and memset works at
byte level. each byte it fills with 0x0b, but an integer is 4 bytes,
so you get 0x0b0b0b0b

hth
jc
Igor Tandetnik
2009-09-10 19:30:25 UTC
Permalink
Post by Robby
Post by Nathan Mates
That'll fill all 400 *bytes* of the h array. memset's middle
parameter is also a *byte* fill pattern. So, filling an integer with
11, like above will fill it with hex 0x0B0B0B0B, or decimal
185273099. For that reason, memset's middle parameter is best passed
in as 0, 0xFF, or some other low-level known value.
I was wondering where that "185273099" was coming from.
So now I understand why everyone was saying that memset is best used
with 0. Or as you pointed out 0xFF (or 255 decimal)!
If you ever get out of C woods back into the sunny land of C++, you
could do

#include <algorithm>

int h[100];
std::fill(h, h + 100, 11);
// or
std::fill_n(h, 100, 11);
--
With best wishes,
Igor Tandetnik

With sufficient thrust, pigs fly just fine. However, this is not
necessarily a good idea. It is hard to be sure where they are going to
land, and it could be dangerous sitting under them as they fly
overhead. -- RFC 1925
Robby
2009-09-11 14:55:01 UTC
Permalink
Post by Igor Tandetnik
If you ever get out of C woods back into the sunny land of C++, you
could do
#include <algorithm>
int h[100];
std::fill(h, h + 100, 11);
// or
std::fill_n(h, 100, 11);
A *good* C++ compiler for MCU's is quite expensive these days.
I am currently looking into a C++ compiler, but don't know if I will buy it.
Perhaps someday I could stop anoying you with C.
--
Best regards
Roberto
Post by Igor Tandetnik
Post by Robby
Post by Nathan Mates
That'll fill all 400 *bytes* of the h array. memset's middle
parameter is also a *byte* fill pattern. So, filling an integer with
11, like above will fill it with hex 0x0B0B0B0B, or decimal
185273099. For that reason, memset's middle parameter is best passed
in as 0, 0xFF, or some other low-level known value.
I was wondering where that "185273099" was coming from.
So now I understand why everyone was saying that memset is best used
with 0. Or as you pointed out 0xFF (or 255 decimal)!
If you ever get out of C woods back into the sunny land of C++, you
could do
#include <algorithm>
int h[100];
std::fill(h, h + 100, 11);
// or
std::fill_n(h, 100, 11);
--
With best wishes,
Igor Tandetnik
With sufficient thrust, pigs fly just fine. However, this is not
necessarily a good idea. It is hard to be sure where they are going to
land, and it could be dangerous sitting under them as they fly
overhead. -- RFC 1925
Vincent Fatica
2009-09-10 02:04:09 UTC
Permalink
On Wed, 9 Sep 2009 18:14:01 -0700, Robby <***@discussions.microsoft.com>
wrote:

|int h[100];
|memset(h,11,100);
|
|for(i=0; i<100; i++)
|t = h[i]; // t does not retrieve the right innitialized values from h !
|
|return 0;
|}
|==================================
|
|The actual definition of memset is:
|
|"The most common use of memset() is to initialize a region of memory to some
|value."
|
|So isn't an array of integers a valid region of memory that can be set by
|memset?

Your memset, above, sets 100 (consecutive) **bytes**, each to 11 (0x0B). memset
can be used, carefully, on other things but it always fills and counts chars
(bytes).

You could, for example,

memset(h, 11, 100 * sizeof(int));

and wind up with 100 ints each with the value 0x0B0B0B0B. There doesn't seem to
be much reason to do that, but to set all 100 ints to 0, you can

memset(h, 0, 100 * sizeof(int));
--
- Vince
Bo Persson
2009-09-10 20:17:54 UTC
Permalink
Post by Vincent Fatica
On Wed, 9 Sep 2009 18:14:01 -0700, Robby
Post by Robby
int h[100];
memset(h,11,100);
for(i=0; i<100; i++)
t = h[i]; // t does not retrieve the right innitialized values from h !
return 0;
}
==================================
"The most common use of memset() is to initialize a region of
memory to some value."
So isn't an array of integers a valid region of memory that can be
set by memset?
Your memset, above, sets 100 (consecutive) **bytes**, each to 11
(0x0B). memset can be used, carefully, on other things but it
always fills and counts chars (bytes).
You could, for example,
memset(h, 11, 100 * sizeof(int));
and wind up with 100 ints each with the value 0x0B0B0B0B. There
doesn't seem to be much reason to do that, but to set all 100 ints
to 0, you can
memset(h, 0, 100 * sizeof(int));
But if you want all the ints to be zero, you can initialize the array
directly.

int h[100] = {0};

This will set the first element to 0, and all the rest to their
default value of ... eh ... zero.



Bo Persson
Robby
2009-09-11 14:56:01 UTC
Permalink
Post by Bo Persson
But if you want all the ints to be zero, you can initialize the array
directly.
int h[100] = {0};
This will set the first element to 0, and all the rest to their
default value of ... eh ... zero.
That's neat!

Thanks all!
--
Best regards
Roberto
Post by Bo Persson
Post by Vincent Fatica
On Wed, 9 Sep 2009 18:14:01 -0700, Robby
Post by Robby
int h[100];
memset(h,11,100);
for(i=0; i<100; i++)
t = h[i]; // t does not retrieve the right innitialized values from h !
return 0;
}
==================================
"The most common use of memset() is to initialize a region of
memory to some value."
So isn't an array of integers a valid region of memory that can be
set by memset?
Your memset, above, sets 100 (consecutive) **bytes**, each to 11
(0x0B). memset can be used, carefully, on other things but it
always fills and counts chars (bytes).
You could, for example,
memset(h, 11, 100 * sizeof(int));
and wind up with 100 ints each with the value 0x0B0B0B0B. There
doesn't seem to be much reason to do that, but to set all 100 ints
to 0, you can
memset(h, 0, 100 * sizeof(int));
But if you want all the ints to be zero, you can initialize the array
directly.
int h[100] = {0};
This will set the first element to 0, and all the rest to their
default value of ... eh ... zero.
Bo Persson
Vincent Fatica
2009-09-11 17:09:20 UTC
Permalink
On Fri, 11 Sep 2009 07:56:01 -0700, Robby <***@discussions.microsoft.com>
wrote:

|>But if you want all the ints to be zero, you can initialize the array
|>directly.
|
|>int h[100] = {0};
|
|>This will set the first element to 0, and all the rest to their
|>default value of ... eh ... zero.
|
|That's neat!

Similarly, and often useful is the likes of

STARTUPINFO si = {sizeof(si), 0};

All members of si after the first (si.cb) will be initialized to 0.
--
- Vince
Vincent Fatica
2009-09-11 17:19:47 UTC
Permalink
On 11 Sep 2009 13:09:20 -0400, Vincent Fatica <***@blackholespam.net> wrote:

||That's neat!
|
|Similarly, and often useful is the likes of
|
| STARTUPINFO si = {sizeof(si), 0};
|
|All members of si after the first (si.cb) will be initialized to 0.

And though you may not realize it, the same thing happens when you say

CHAR szFileName[MAX_PATH] = "dummy.txt";

The tail of the array will be filled with 0's because "dummy.txt" is
NUL-terminated; actually

{'d', 'u', 'm', 'm', 'y', '.', 't', 'x', 't', 0}
--
- Vince
Barry Schwarz
2009-09-12 00:19:06 UTC
Permalink
On 11 Sep 2009 13:19:47 -0400, Vincent Fatica
Post by Vincent Fatica
||That's neat!
|
|Similarly, and often useful is the likes of
|
| STARTUPINFO si = {sizeof(si), 0};
|
|All members of si after the first (si.cb) will be initialized to 0.
And though you may not realize it, the same thing happens when you say
CHAR szFileName[MAX_PATH] = "dummy.txt";
The tail of the array will be filled with 0's because "dummy.txt" is
NUL-terminated; actually
{'d', 'u', 'm', 'm', 'y', '.', 't', 'x', 't', 0}
No. All the elements up through szFileName[9] (including the first
'\0') are initialized by the provided initialization data. All
subsequent elements are set to 0 by the rule (in 6.7.8-19 for C) any
subobjects not specifically initialized shall be initialized as if
they were static.

The resulting value in szFileName would be exactly the same if the
initialization was written as
{'d', 'u', 'm', 'm', 'y', '.', 't', 'x', 't'}
even though the initialization does not specify a '\0' value.

The fact that the last character in the string literal is the same as
the value used to initialize the remaining elements of the array is
essentially coincidental.
--
Remove del for email
Vincent Fatica
2009-09-12 02:00:54 UTC
Permalink
On Fri, 11 Sep 2009 17:19:06 -0700, Barry Schwarz <***@dqel.com> wrote:

|No. All the elements up through szFileName[9] (including the first
|'\0') are initialized by the provided initialization data. All
|subsequent elements are set to 0 by the rule (in 6.7.8-19 for C) any
|subobjects not specifically initialized shall be initialized as if
|they were static.
|
|The resulting value in szFileName would be exactly the same if the
|initialization was written as
| {'d', 'u', 'm', 'm', 'y', '.', 't', 'x', 't'}
|even though the initialization does not specify a '\0' value.

OK, thanks. I didn't know that. I'm pretty sure I've seem numerous examples
using the array form of the initializer **with** the trailing '\0' (and thought
it was necessary).
--
- Vince
Barry Schwarz
2009-09-12 16:00:50 UTC
Permalink
On 11 Sep 2009 22:00:54 -0400, Vincent Fatica
Post by Vincent Fatica
|No. All the elements up through szFileName[9] (including the first
|'\0') are initialized by the provided initialization data. All
|subsequent elements are set to 0 by the rule (in 6.7.8-19 for C) any
|subobjects not specifically initialized shall be initialized as if
|they were static.
|
|The resulting value in szFileName would be exactly the same if the
|initialization was written as
| {'d', 'u', 'm', 'm', 'y', '.', 't', 'x', 't'}
|even though the initialization does not specify a '\0' value.
OK, thanks. I didn't know that. I'm pretty sure I've seem numerous examples
using the array form of the initializer **with** the trailing '\0' (and thought
it was necessary).
If the size of the array is specified as [], the trailing '\0' would
be necessary because the compiler will compute the number of elements
based solely on the quantity of initialization values rather than
assume you wanted a properly terminated string. If you leave out the
'\0', the resulting array is not a string because it is not
terminated.

In this code, the number of elements was specified in the definition
of the array so the "extra subobjects" rule applies.
--
Remove del for email
Igor Tandetnik
2009-09-11 17:40:47 UTC
Permalink
Post by Vincent Fatica
On Fri, 11 Sep 2009 07:56:01 -0700, Robby
Post by Robby
Post by Bo Persson
But if you want all the ints to be zero, you can initialize the
array directly.
int h[100] = {0};
This will set the first element to 0, and all the rest to their
default value of ... eh ... zero.
That's neat!
Similarly, and often useful is the likes of
STARTUPINFO si = {sizeof(si), 0};
Or simply

STARTUPINFO si = {sizeof(si)};
--
With best wishes,
Igor Tandetnik

With sufficient thrust, pigs fly just fine. However, this is not
necessarily a good idea. It is hard to be sure where they are going to
land, and it could be dangerous sitting under them as they fly
overhead. -- RFC 1925
Tamas Demjen
2009-09-11 20:34:11 UTC
Permalink
Post by Robby
Post by Bo Persson
int h[100] = {0};
This will set the first element to 0, and all the rest to their
default value of ... eh ... zero.
That's neat!
Or even
int h[100] = {};

Note, however, that
int h[100] = { 11 };

won't set every item to 11. It sets the first item to 11, and the rest to 0.

Tom
Bo Persson
2009-09-12 08:32:05 UTC
Permalink
Post by Tamas Demjen
Post by Robby
Post by Bo Persson
int h[100] = {0};
This will set the first element to 0, and all the rest to their
default value of ... eh ... zero.
That's neat!
Or even
int h[100] = {};
Yes, but some stupid compilers will issue a warning for this, assuming
that you have forgotten the values. :-(
Post by Tamas Demjen
Note, however, that
int h[100] = { 11 };
won't set every item to 11. It sets the first item to 11, and the rest to 0.
True.


Bo Persson
Igor Tandetnik
2009-09-12 14:03:03 UTC
Permalink
Post by Bo Persson
Post by Tamas Demjen
Post by Robby
Post by Bo Persson
int h[100] = {0};
This will set the first element to 0, and all the rest to their
default value of ... eh ... zero.
That's neat!
Or even
int h[100] = {};
Yes, but some stupid compilers will issue a warning for this, assuming
that you have forgotten the values. :-(
In C, {} is not a valid initializer. In C++ it is.
--
With best wishes,
Igor Tandetnik

With sufficient thrust, pigs fly just fine. However, this is not
necessarily a good idea. It is hard to be sure where they are going to
land, and it could be dangerous sitting under them as they fly
overhead. -- RFC 1925
Robby
2009-09-12 15:44:02 UTC
Permalink
All of this is interesting.

Thankyou all for your feedback!
--
Sincere regards
Roberto
Post by Igor Tandetnik
Post by Bo Persson
Post by Tamas Demjen
Post by Robby
Post by Bo Persson
int h[100] = {0};
This will set the first element to 0, and all the rest to their
default value of ... eh ... zero.
That's neat!
Or even
int h[100] = {};
Yes, but some stupid compilers will issue a warning for this, assuming
that you have forgotten the values. :-(
In C, {} is not a valid initializer. In C++ it is.
--
With best wishes,
Igor Tandetnik
With sufficient thrust, pigs fly just fine. However, this is not
necessarily a good idea. It is hard to be sure where they are going to
land, and it could be dangerous sitting under them as they fly
overhead. -- RFC 1925
Continue reading on narkive:
Loading...