Note: Do not cast void *
(result of malloc()
) to other pointers and always check the result of malloc()
& friends.
Memset takes an unsigned char (most likely 8 bits) and treats the area passed as an array of char. It has no idea of structs, arrays etc. Just of a 1-dimensional array of char. (as @chqrlie noted, memset()
actually takes an int
; this is, however, internally converted to unsigned char
).
The segfault is because you pass the address of cArray
which is a pointer to the actual array, not its value which would be the array itself.
For float, memset() most likely only makes sense setting it to all-0
:
memset(cArray, 0, sizeof(struct color) * w * h);
Note: memset has no idea on data types. It just takes a pointer to a block of memory and a count and stores the value to that area. It is your responsibility all arguments are valid!
Note that writing the memory area with 0
is actually float zero (0.0
, actually +0.0
), as that has all bits cleared. That was a briliant intention by the guys who dsigned the encoding for floats.
As you allocate right before, you can combine this using calloc()
. That will allocate and clear the memory area of the array. However, if you intend to set all values explicitly anyway, you better stick with malloc()
.
If you want to set other float values, you have to write your own loop. However, you can threat the array as 1-dimensional for that.
for ( size_t i = 0 ; i < w * h ; i++ )
cArray[i] = (struct color){ .r = 1.0, .g = 1.0, .b = 1.0 };
That uses a compound literal. Alternatively you can also set the fields seperately.
If you are upt for speed, the compount-literal approach might be the fastest. This way ,the compiler might very well load al values into three registers and store them directly into memory using store-multiple. However it might do, I would bet the compiler will recognize that pattern and optimize as hell, as it is commonly used for very large loops.