Is memset used only for strings?

F

Frederick Ding

Hi, guys,I met a problem, Please look at the problem below:

int* bit = (int*)malloc(10000*sizeof(int));
memset(bit, 1, 10000*sizeof(int));
printf("%d %d %d\n", bit[1],bit[2], bit[9999]);

Output: 16843009 16843009 16843009

Obviously I set the bit[0] to bit[9999] to 1, but it outputs are not
1's.

Why is this happen? Do I misused memset or sth else?

Any help is appreciated. Thanks!
 
R

Richard Heathfield

Frederick Ding said:
Hi, guys,I met a problem, Please look at the problem below:

int* bit = (int*)malloc(10000*sizeof(int));

int *bit = malloc(10000 * sizeof *bit);

if(bit != NULL)
{
memset(bit, 1, 10000*sizeof(int));

Oops - that won't do what you were hoping.
printf("%d %d %d\n", bit[1],bit[2], bit[9999]);

Output: 16843009 16843009 16843009

Obviously I set the bit[0] to bit[9999] to 1, but it outputs are not
1's.

Observe this magic:

unsigned char *p = (unsigned char *)bit;
while(p < (unsigned char *)(bit + 1))
{
printf("%d\n", *p++)
}

This prints every byte in your first int. Try it, and I think you'll
understand all about memset.
 
?

=?ISO-8859-1?Q?Bj=F8rn_Augestad?=

Frederick said:
Hi, guys,I met a problem, Please look at the problem below:

int* bit = (int*)malloc(10000*sizeof(int));
memset(bit, 1, 10000*sizeof(int));
printf("%d %d %d\n", bit[1],bit[2], bit[9999]);

Output: 16843009 16843009 16843009

Obviously I set the bit[0] to bit[9999] to 1, but it outputs are not
1's.

Why is this happen? Do I misused memset or sth else?

Any help is appreciated. Thanks!

Your call to memset() sets each byte to 1. Your ints probably occupies 4
bytes, so you initialize each int with bit patterns 0x01010101, which
equals 16843009.

Bjørn
 
K

Keith Thompson

Frederick Ding said:
Hi, guys,I met a problem, Please look at the problem below:

int* bit = (int*)malloc(10000*sizeof(int));

Don't cast the result of malloc. It can mask errors such as failing
to include <stdlib.h> or compiling C code with a C++ compiler.

The recommended idiom is:

int *bit = malloc(10000 * sizeof *bit);

You should check whether the malloc() call succeeded.
memset(bit, 1, 10000*sizeof(int));

This sets every byte of the array to 1.
printf("%d %d %d\n", bit[1],bit[2], bit[9999]);

Output: 16843009 16843009 16843009

Obviously I set the bit[0] to bit[9999] to 1, but it outputs are not
1's.

16843009 in hexadecimal is 0x01010101.

memset() sets every byte to a specified value. There's no equivalent
standard function to set every int to a specified value.
 
M

Malcolm

Frederick Ding said:
Obviously I set the bit[0] to bit[9999] to 1, but it outputs are not
1's.

Why is this happen? Do I misused memset or sth else?

Any help is appreciated. Thanks!
memset isn't a very useful function.
It sets every byte to a given value. The only practical use, really, is to
set memory to zero, unless, as you say, you happen to want a string of
asterisks or something.
You cannot set integers to a non-zero value.
You can set pointers to NULL and floating point values to zero, but not with
complete portability (the NULL pointer isn't always all bits zero).

Your best bet is to ignore it and use a for loop, setting your array to the
values you want.
 
A

Alex Fraser

[snip]
memset isn't a very useful function.

I agree.
It sets every byte to a given value. The only practical use, really, is
to set memory to zero, unless, as you say, you happen to want a string of
asterisks or something.
You cannot set integers to a non-zero value.

AFAIK you can't portably set them to zero either, except possibly the
fixed-size ones added in C99 (uint32_t etc).
You can set pointers to NULL and floating point values to zero, but not
with complete portability (the NULL pointer isn't always all bits zero).

Neither, as I'm sure you meant, is a floating point all-bits-zero
necessarily equal to zero.

Alex
 
M

Malcolm

Alex Fraser said:
AFAIK you can't portably set them to zero either, except possibly the
fixed-size ones added in C99 (uint32_t etc).
int array[100];

memset(array, 0, 100 * sizeof(int));

is guaranteed to produce an array to 100 integers of value 0, on an ANSI
system.
(However if technology changes so that for some reason it doesn't make sense
to have value zero all bits clear, the ANSI standard will be a dead letter).
 
E

Emmanuel Delahaye

Frederick Ding a écrit :
Hi, guys,I met a problem, Please look at the problem below:

int* bit = (int*)malloc(10000*sizeof(int));
memset(bit, 1, 10000*sizeof(int));
printf("%d %d %d\n", bit[1],bit[2], bit[9999]);

Output: 16843009 16843009 16843009

Many things are missing. It may work or not...
Obviously I set the bit[0] to bit[9999] to 1, but it outputs are not
1's.

Assuming the code is complete, yes there are. It will appears more
clearly like this:

#include <stdlib.h>
#include <string.h>
#include <stdio.h>

int main(void)
{
size_t const size = 10000;
int* bit = malloc (size * sizeof *bit);

if (bit != NULL)
{
memset(bit, 1, size * sizeof *bit);
printf("%X %X %X\n"
, (unsigned) bit[1]
, (unsigned) bit[2]
, (unsigned) bit[size-1]);

free (bit), bit = NULL;
}

return 0;
}

1010101 1010101 1010101

see the pattern ?
 
E

Emmanuel Delahaye

Frederick Ding a écrit :
Hi, guys,I met a problem, Please look at the problem below:

int* bit = (int*)malloc(10000*sizeof(int));
memset(bit, 1, 10000*sizeof(int));
printf("%d %d %d\n", bit[1],bit[2], bit[9999]);

Output: 16843009 16843009 16843009

Many things are missing. It may work or not...

Please don't forget to free what have been allocated :

<<SYSALLOC Bloc 003D4A70 (40000 bytes) malloc'ed at line 14 of 'main.c'
not freed>>
Obviously I set the bit[0] to bit[9999] to 1, but it outputs are not
1's.

Assuming the code is complete, yes there are. It will appears more
clearly like this:

#include <stdlib.h>
#include <string.h>
#include <stdio.h>

int main(void)
{
size_t const size = 10000;
int* bit = malloc (size * sizeof *bit);

if (bit != NULL)
{
memset(bit, 1, size * sizeof *bit);
printf("%X %X %X\n"
, (unsigned) bit[1]
, (unsigned) bit[2]
, (unsigned) bit[size-1]);

free (bit), bit = NULL;
}

return 0;
}

1010101 1010101 1010101

see the pattern ?
 
F

Frederick Ding

Thanks, guys!
I'm very happy that so many kind people help me.
I've learned a lot from you, THANKS!
Yet I still have two questions:
1. malloc(10000 * sizeof *bit);
^^^^^^^^^^^^
sizeof *bit what's this, can sizeof be used like this? wow,
I can not find this expression in all of my C books.
where can I find some reference to this?
I think sizeof is a function that calculate a type's size, so it
should be used with ( ),
and the * between "sizeof" and "bit" is a pointer or a multiply? I'm
really confused.

2. I once used memset like this, and it looked like works:
memset(semi,-1,sizeof(float)*16);
memset(final,-1,sizeof(float)*16);
memset(cup,-1,sizeof(float)*16);
printf("%f %f\n",semi[0],final[15]);

Output: -1.#QNAN0 -1.#QNAN0
It seemed that it was "-1" and I omitted the topic I just asked.
Now the question is "-1.#QNAN0" means what?
what is the #QNAN0?

Thank you for your patience and time!
 
P

pete

Alex Fraser wrote:
AFAIK you can't portably set them to zero either, except possibly the
fixed-size ones added in C99 (uint32_t etc).

For character sets, a byte with all bits zero,
is a valid null character.
 
M

Mark McIntyre

Thanks, guys!
I'm very happy that so many kind people help me.
I've learned a lot from you, THANKS!
Yet I still have two questions:
1. malloc(10000 * sizeof *bit);
^^^^^^^^^^^^
sizeof *bit what's this, can sizeof be used like this?

sizeof is an operator, not a function. Its operand must be either a
type or an object. If the operand is an object, it doesn't need the
parens.
where can I find some reference to this?

The ISO C standard
6.5.3.4 The sizeof operator
Constraints
1 The sizeof operator shall not be applied to an expression that has
function type or an incomplete type, to the parenthesized name of such
a type, or to an expression that designates a bit-field member.
Semantics
2 The sizeof operator yields the size (in bytes) of its operand, which
may be an expression or the parenthesized name of a type.
I think sizeof is a function that calculate a type's size, so it
should be used with ( ),

No, its an operator
and the * between "sizeof" and "bit" is a pointer or a multiply?

No, its the indirection operator, same as in
int *bit;
2. I once used memset like this, and it looked like works:
memset(semi,-1,sizeof(float)*16);

Output: -1.#QNAN0 -1.#QNAN0
It seemed that it was "-1" and I omitted the topic I just asked.
Now the question is "-1.#QNAN0" means what?

it means your number is Not A Number. Clearly setting all bytes of a
float to -1 on your system causes the float to be a non-number.
 
E

Emmanuel Delahaye

Frederick Ding a écrit :
Thanks, guys!
I'm very happy that so many kind people help me.
I've learned a lot from you, THANKS!
Yet I still have two questions:
1. malloc(10000 * sizeof *bit);
^^^^^^^^^^^^
sizeof *bit what's this, can sizeof be used like this? wow,
I can not find this expression in all of my C books.

It's a short way for sizeof p[0] that can be written *(p + 0), hence
*(p) hence finally *p.

It means 'the size of the first element of the pointed array'.
where can I find some reference to this?

Pointer arithmetics.
I think sizeof is a function that calculate a type's size, so it

Nope. sizeof is a unary operator. It works like this :

size_t size = sizeof object
size_t size = sizeof (type)
should be used with ( ),

It depends on the context. Note that an excess of parenthesis is
harmless (kinda belt and suspensers strategy !).
and the * between "sizeof" and "bit" is a pointer or a multiply?

None of them. It's the indirection operator (or dereference operator).
2. I once used memset like this, and it looked like works:
memset(semi,-1,sizeof(float)*16);

Don't use memset() on floating points. The result is implementation
dependent or more likely undefined.
memset(final,-1,sizeof(float)*16);
memset(cup,-1,sizeof(float)*16);
printf("%f %f\n",semi[0],final[15]);

Output: -1.#QNAN0 -1.#QNAN0
It seemed that it was "-1" and I omitted the topic I just asked.
Now the question is "-1.#QNAN0" means what?
what is the #QNAN0?

NAN means Not A Number. IOW, the internal format is undefined. Once
again, don't to that. What did you intent to do ?
 
M

Mark McIntyre

Frederick Ding a écrit :

NAN means Not A Number. IOW, the internal format is undefined.

See for example:
http://stevehollasch.com/cgindex/coding/ieeefloat.html
if you examine the bitpattern your memset created, and compare it to
the table near the bottom, all will be revealed.
Once again, don't to that. What did you intent to do ?

I imagine he wante to set all his floats to value -1. To the OP:
memset does /exactly/ what it says on the tin - sets n bytes of memory
to value m. It does NOT set the value of the variable to n.
 
A

Alex Fraser

Malcolm said:
Alex Fraser said:
AFAIK you can't portably set them to zero either, except possibly the
fixed-size ones added in C99 (uint32_t etc).

int array[100];

memset(array, 0, 100 * sizeof(int));

is guaranteed to produce an array to 100 integers of value 0, on an ANSI
system.

"All bits zero" implies "all padding bits zero" and I don't see why that
couldn't be a trap representation for int.

Alex
 
A

Alex Fraser

pete said:
Alex said:
AFAIK you can't portably set [integers] to zero [with memset] either,
except possibly the fixed-size ones added in C99 (uint32_t etc).

For character sets, a byte with all bits zero,
is a valid null character.

Noted.

Alex
 
K

Keith Thompson

Alex Fraser said:
Malcolm said:
Alex Fraser said:
It sets every byte to a given value. The only practical use, really,
is to set memory to zero, unless, as you say, you happen to want a
string of asterisks or something.
You cannot set integers to a non-zero value.

AFAIK you can't portably set them to zero either, except possibly the
fixed-size ones added in C99 (uint32_t etc).

int array[100];

memset(array, 0, 100 * sizeof(int));

is guaranteed to produce an array to 100 integers of value 0, on an ANSI
system.

"All bits zero" implies "all padding bits zero" and I don't see why that
couldn't be a trap representation for int.

The response to Defect Report #263 says:

For any integer type, the object representation where all the bits
are zero shall be a representation of the value zero in that type.

This is published in Technical Corrigendum 2, and appears in n1124
(which includes the C99 standard with TC1 and TC2 merged in).
 
A

Alex Fraser

Keith Thompson said:
The response to Defect Report #263 says:

For any integer type, the object representation where all the bits
are zero shall be a representation of the value zero in that type.

This is published in Technical Corrigendum 2, and appears in n1124
(which includes the C99 standard with TC1 and TC2 merged in).

Thank you.

Alex
 

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

Forum statistics

Threads
473,755
Messages
2,569,534
Members
45,008
Latest member
Rahul737

Latest Threads

Top