tags:

views:

2946

answers:

5

This is the code that I want to try to write:

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

int main(int argc, char *argv[])
{
    float arry[3] = {0};

    memset(arry, (int) 10.0, 3*sizeof(float));

    return 0;
}

My problem is that I want to see if it's possible to use memset to make every entry of an array to be a number other than 0. However, After stepping through that line, the array contents change to a very small number (0). I wonder what I'm doing wrong in this case with using the memset() function. I hope this isn't a duplicate post, as none of the suggested related questions as I'm typing this appears to be.

+6  A: 

No. memset takes a single byte and writes it to the array. A float is a multi-byte type.

EDIT: Yes, I know memset takes an int. But it only uses an unsigned char (a single byte) to fill with.

Michael Kohne
+5  A: 

Casting a double to an int just creates the binary number 00001010 (10 in binary), and that is the value that is memset'ed. Since it's a char, each of your floats is actually receiving the bit pattern 00001010 00001010 00001010 00001010.

Jim Buck
i.e. it only makes sense to use it to reset the entries of an array to zeros, practically speaking?
stanigator
That or if you are setting up a char array that has some other value that is relevant.
Jim Buck
Or any single byte value. The most common is probably 0, but 0xFF is also likely to be used a lot.
Michael Kohne
Thanks for the explanations.
stanigator
Or any integer (short, int, long etc.) value if you need all bytes of each integer the same. 0 and 0xFF being the most likely candidates.
Steve Fallows
As an example, I just programmed a use of this. It is a structure of parameters that get passed to some GUI dialog of sorts, I memset the whole structure to 0x00 since that bit pattern works for everything (pointers, floats, etc.) before setting only the couple fields I care about.
Jim Buck
+5  A: 

Memset takes a int, but casts it to an unsigned char, and then fills each byte of float (sizeof(float) is probably 4) with that bit pattern. If this is c++, prefer fill instead:

#include <algorithm>
using namespace std;

//...

fill (arry,arry+3,10.0);
Todd Gardner
Great suggestion. I will look into using it.
stanigator
And if you're in C not C++, then look about for platform-specific memset variants which write larger patterns than a single char. There's memset_pattern4 for instance if you have it. Or SIMD instructions.
Steve Jessop
+1  A: 

Actually your try is a little bit misleading, memset works on bytes.. actually using a float for memset value doesn't make any sense!

The float format just has 23+1 bits for mantissa and 8 bits for exponent.. when you write raw bytes values (using memset) inside a float you don't know what you are obtaining because you are setting values that will be interpreted in a different way!

In your snippet you also cast it to (int) turning a 4-bytes float containing 10.0f in a 4-bytes integer containing the value 10.. but as said before if you memset a float with 10 (= 0x0a) you'll end up obtaining 0x0A0A0A0A that is not 10.0f in float format, it can be whatever value (also something very near to 0, like in your case).

Actually memset is useful when you want to initialize an array of chars (since you obtain effectively that value for every char because they are 1 byte long) or when you want to set everything to 0 (NULL) that works for every basic kind of data..

Jack
+1  A: 

Why not just a simple for loop?

Mark Jones
The need for speed is one answer.
EvilTeach
The whole point of my question actually.
stanigator
All memset's going to do is set the memory one byte at the time. A for loop will zip through sizeof(arry) bytes sizeof(float) bytes at a time. And without the overhead of a function call!
Mark Jones
@Mark Jones: The difference is that memset can take advantage of the inbuilt string handling instructions of the CPU, making the operation somewhat faster.
DrJokepu