I have initialised the entire array with value 1 but the output is showing some garbage value. But this program works correctly if i use 0 or -1 in place of 1. So are there some restrictions on what type of values can be initialised using memset.
int main(){
int a[100];
memset(a,1,sizeof(a));
cout<<a[5]<<endl;
return 0;
}
memset, as the other say, sets every byte of the array at the specified value.
The reason this works with 0 and -1 is because both use the same repeating pattern on arbitrary sizes:
(int) -1 is 0xffffffff
(char) -1 is 0xff
so filling a memory region with 0xff will effectively fill the array with -1.
However, if you're filling it with 1, you are setting every byte to 0x01; hence, it would be the same as setting every integer to the value 0x01010101, which is very unlikely what you want.
Memset fills bytes, from cppreference:
Converts the value ch to unsigned char and copies it into each of the first count characters of the object pointed to by dest.
Your int takes several bytes, e.g. a 32bit int will be filled with 1,1,1,1 (in base 256, endianess doesn't matter in this case), which you then falsly interpreted as a "garbage" value.
The other answers have explained std::memset already. But it's best to avoid such low level features and program at a higher level. So just use the Standard Library and its C++11 std::array
#include <array>
std::array<int, 100> a;
a.fill(1);
Or if you prefer C-style arrays, still use the Standard Library with the std::fill algorithm as indicated by #BoPersson
#include <algorithm>
#include <iterator>
int a[100];
std::fill(std::begin(a), std::end(a), 1);
In most implementations, both versions will call std::memset if it is safe to do so.
memset is an operation that sets bits.
If you want to set a value use a for-loop.
Consider a 4-bit-integer:
Its value is 1 when the bits are 0001 but memset sets it to 1111
Related
I wonder what is the ideal way if you want to fill an array with a default value n:
#include <cstring> // for memset
#include <algorithm> // for fill_n
static constexpr int N = 100;
int a[N];
static constexpr int defaultValue = -1;
void* memset( void* dest, int ch, std::size_t count );
memset(a, defaultValue, sizeof(a));
(memset) converts the value ch to unsigned char and copies it into each of the first count characters of the object pointed to by dest. If the object is a potentially-overlapping subobject or is not TriviallyCopyable (e.g., scalar, C-compatible struct, or an array of trivially copyable type), the behavior is undefined. If count is greater than the size of the object pointed to by dest, the behavior is undefined.
or
constexpr OutputIt fill_n( OutputIt first, Size count, const T& value );
fill_n(a, N, defaultValue);
(fill_n) assigns the given value to the first count elements in the range beginning at first if count > 0. Does nothing otherwise.
I am looking for insights, I know how to read the documentation of course!
edit: defaultValue might not be only -1.
Both functions do different things. Sure, they fill a block of memory, but the way they do it is completely different.
memset operates at the byte level. defaultValue is hacked down to an unsigned char, so a defaultValue greater than what can fit into a single byte gets cut down to size and information is lost. The now-byte-sized value is applied individually to every byte, not every int in the array. In the case of -1 you get "lucky" because four bytes worth of 0xFF looks the same, 0xFFFFFFFF, as a two's compliment -1 in the world of 32-bit integers. No such luck for most other numbers. 1, for example, will not result in an array full of int's set to 1, it's filled with 0x01010101, or 16843009.
fill_n , on the other hand, respects the array element's type. Every int in the array will be set to defaultValue. in the case of a defaultValue of 1, the array will be full of 1s. defaultValue of 256, provides an array full of 256.
In terms of speed, it probably won't matter much. Memory read or written in bytes is a rare sight these days. Writing whole ints at a time may be faster. But a good memset implementation knows this and will be exploiting it. If it doesn't, the compiler likely will.
I want to set all the index value to -1 in a double array.
Here is my code :
double dp[505];
memset(dp,-1,sizeof(dp));
cout<<dp[0]<<"\n";
But it is showing nan when i try to print its value.
What does nan mean?
Is it possible to use memset() in double array?
In C++, you can write:
double initValue = -1;
std::fill_n(dp, 505, initValue);
memsetting a double array with a non-double value won't work.
memset operates on bytes, not floats, and a double with all bytes set to -1 does not equal -1. I think you're looking for std::fill:
#include <algorithm>
std::fill(dp, dp + 505, -1.0);
Or, in C++11:
#include <algorithm>
#include <iterator>
std::fill(std::begin(dp), std::end(dp), -1.0);
You have set each element of the array to be filled with the byte 0xFF (i.e. the char representation of -1).
No floating point number is represented by a series of 0xFF bytes, so on printing the double, you see NaN (i.e. 'not a number'). This is in apparent contrast to memset'ting the bytes to zero, which is legal as a string of 0 bytes is a double with value zero. See Is it legal to use memset(,0,) on array of doubles?.
If you meant to set every entry to -1.0 (i.e. a double), then use std::fill or std::fill_n in C++ or a loop in C, e.g.
int n;
for (n = 0 ; n < 505 ; n++)
dp[n] = -1.0;
From the man page of memset:
The memset() function fills the first n bytes of the memory area pointed to by s with the constant byte c.
The problem is that you want to fill an array of doubles with the constant -1.0 but sizeof(double) > 1 so memset actually fills in garbage which happens to end up as a NaN.
If you are using C++, the std::fill function is your friend. Actually, since you are writing to your array for the first time, std::uninitialized_fill would be correct. Although for the builtin double type there should be no difference but it is always good to be precise.
constexpr std::size_t length = 505;
double values[length];
std::uninitialized_fill(values, values + length, -1.0);
memset sets bytes, so you get double-values where each byte is -1.
Instead in C++ use std::vector, then write
vector<double> dp( 505, -1.0 );
It's that simple.
If dp is a global vector and you need to set it to -1 a number of times, then you can simply do this:
dp = vector<double>( dp.size(), -1.0 );
However, it's generally not a good idea to use non-const global variables.
Alternatively one can use std::fill, or just a loop, or just about any technique that still treat the double values as double values. But std::vector is preferable also for many other reasons than greatly simplifying the fill-it task. In particular a std::vector can be resized, it takes care of copying, and it automates the memory management, doing that part correctly and transparent to you.
nan means not a number.
cant see why its not working.
maybe because precision is not set : (cout.precision(15);)
check this:
How do I print a double value with full precision using cout?
But im not sure at all it will works :o
i checked memset source code and there's no problem with negative :D
But it can be a problem with doubles :
memset(dst0, c0, length) void *dst0;
register int c0;
register size_t length;
Have you tried to compile with Werror flag ?
Although answers for you question have been given, I just wanted you to note that
sizeof(dp)
outputs the number of bytes used to code the variable in memory.
In your case, dp is a pointer to a double. It will then be equal to the size of a pointer (4), no matter wether or not memery has been allocated.
sizeof(*dp) will output the size of a double (8).
In order to use the length of a
Can't seem to find the answer to this anywhere,
How do I memset an array to the maximum value of the array's type?
I would have thought memset(ZBUFFER,0xFFFF,size) would work where ZBUFFER is a 16bit integer array. Instead I get -1s throughout.
Also, the idea is to have this work as fast as possible (it's a zbuffer that needs to initialize every frame) so if there is a better way (and still as fast or faster), let me know.
edit:
as clarification, I do need a signed int array.
In C++, you would use std::fill, and std::numeric_limits.
#include <algorithm>
#include <iterator>
#include <limits>
template <typename IT>
void FillWithMax( IT first, IT last )
{
typedef typename std::iterator_traits<IT>::value_type T;
T const maxval = std::numeric_limits<T>::max();
std::fill( first, last, maxval );
}
size_t const size=32;
short ZBUFFER[size];
FillWithMax( ZBUFFER, &ZBUFFER[0]+size );
This will work with any type.
In C, you'd better keep off memset that sets the value of bytes. To initialize an array of other types than char (ev. unsigned), you have to resort to a manual for loop.
-1 and 0xFFFF are the same thing in a 16 bit integer using a two's complement representation. You are only getting -1 because either you have declared your array as short instead of unsigned short. Or because you are converting the values to signed when you output them.
BTW your assumption that you can set something except bytes using memset is wrong. memset(ZBUFFER, 0xFF, size) would have done the same thing.
In C++ you can fill an array with some value with the std::fill algorithm.
std::fill(ZBUFFER, ZBUFFER+size, std::numeric_limits<short>::max());
This is neither faster nor slower than your current approach. It does have the benefit of working, though.
Don't attribute speed to language. That's for implementations of C. There are C compilers that produce fast, optimal machine code and C compilers that produce slow, inoptimal machine code. Likewise for C++. A "fast, optimal" implementation might be able to optimise code that seems slow. Hence, it doesn't make sense to call one solution faster than another. I'll talk about the correctness, and then I'll talk about performance, however insignificant it is. It'd be a better idea to profile your code, to be sure that this is in fact the bottleneck, but let's continue.
Let us consider the most sensible option, first: A loop that copies int values. It is clear just by reading the code that the loop will correctly assign SHRT_MAX to each int item. You can see a testcase of this loop below, which will attempt to use the largest possible array allocatable by malloc at the time.
#include <limits.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(void) {
size_t size = SIZE_MAX;
volatile int *array = malloc(size);
/* Allocate largest array */
while (array == NULL && size > 0) {
size >>= 1;
array = malloc(size);
}
printf("Copying into %zu bytes\n", size);
for (size_t n = 0; n < size / sizeof *array; n++) {
array[n] = SHRT_MAX;
}
puts("Done!");
return 0;
}
I ran this on my system, compiled with various optimisations enabled (-O3 -march=core2 -funroll-loops). Here's the output:
Copying into 1073741823 bytes
Done!
Process returned 0 (0x0) execution time : 1.094 s
Press any key to continue.
Note the "execution time"... That's pretty fast! If anything, the bottleneck here is the cache locality of such a large array, which is why a good programmer will try to design systems that don't use so much memory... Well, then let us consider the memset option. Here's a quote from the memset manual:
The memset() function copies c (converted to an unsigned char) into
each of the first n bytes of the object pointed to by s.
Hence, it'll convert 0xFFFF to an unsigned char (and potentially truncate that value), then assign the converted value to the first size bytes. This results in incorrect behaviour. I don't like relying upon the value SHRT_MAX to be represented as a sequence of bytes storing the value (unsigned char) 0xFFFF, because that's relying upon coincidence. In other words, the main problem here is that memset isn't suitable for your task. Don't use it. Having said that, here's a test, derived from the test above, which will be used to test the speed of memset:
#include <limits.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(void) {
size_t size = SIZE_MAX;
volatile int *array = malloc(size);
/* Allocate largest array */
while (array == NULL && size > 0) {
size >>= 1;
array = malloc(size);
}
printf("Copying into %zu bytes\n", size);
memset(array, 0xFFFF, size);
puts("Done!");
return 0;
}
A trivial byte-copying memset loop will iterate sizeof (int) times more than the loop in my first example. Considering that my implementation uses a fairly optimal memset, here's the output:
Copying into 1073741823 bytes
Done!
Process returned 0 (0x0) execution time : 1.060 s
Press any key to continue.
These tests are likely to vary, however significantly. I only ran them once each to get a rough idea. Hopefully you've come to the same conclusion that I have: Common compilers are pretty good at optimising simple loops, and it's not worth postulating about micro-optimisations here.
In summary:
Don't use memset to fill ints with values (with an exception for the value 0), because it's not suitable.
Don't postulate about optimisations prior to running tests. Don't run tests until you have a working solution. By working solution I mean "A program that solves an actual problem". Once you have that, use your profiler to identify more significant opportunities to optimise!
This is because of two's complement. You have to change your array type to unsigned short, to get the max value, or use 0x7FFF.
for (int i = 0; i < SIZE / sizeof(short); ++i) {
ZBUFFER[i] = SHRT_MAX;
}
Note this does not initialize the last couple bytes, if (SIZE % sizeof(short))
In C, you can do it like Adrian Panasiuk said, and you can also unroll the copy loop. Unrolling means copying larger chunks at a time. The extreme end of loop unrolling is copying the whole frame over with a zero frame, like this:
init()
{
for (int i = 0; i < sizeof(ZBUFFER) / sizeof(ZBUFFER[0]; ++i) {
empty_ZBUFFER[i] = SHRT_MAX;
}
}
actual clearing:
memcpy(ZBUFFER, empty_ZBUFFER, SIZE);
(You can experiment with different sizes of the empty ZBUFFER, from four bytes and up, and then have a loop around the memcpy.)
As always, test your findings, if a) it's worth optimizing this part of the program and b) what difference the different initializing techniques makes. It will depend on a lot of factors. For the last few per cents of performance, you may have to resort to assembler code.
#include <algorithm>
#include <limits>
std::fill_n(ZBUFFER, size, std::numeric_limits<FOO>::max())
where FOO is the type of ZBUFFER's elements.
When you say "memset" do you actually have to use that function? That is only a byte-by-byte assign so it won't work with signed arrays.
If you want to set each value to the maximum you would use something like:
std::fill( ZBUFFER, ZBUFFER+len, std::numeric_limits<short>::max() )
when len is the number of elements (not the size in bytes of your array)
I have allocated a big double vector, lets say with 100000 element. At some point in my code, I want to set all elements to a constant, nonzero value. How can I do this without using a for loop over all elements?
I am also using the blas package, if it helps.
You could use std::fill (#include <algorithm>):
std::fill(v.begin(), v.end(), 1);
This is essentially also only a loop of course..
'fill' is right from what you've said.
Be aware that it's also possible to construct a vector full of a specified value:
std::vector<double> vec(100000, 3.14);
So if "at some point" means "immediately after construction", do this instead. Also, it means you can do this:
std::vector<double>(100000, 3.14).swap(vec);
which might be useful if "at some point" means "immediately after changing the size", and you expect/want the vector to be reallocated ("expect" if you're making it bigger than its prior capacity, "want" if you're making it much smaller and want it trimmed to save memory).
You always use memset() if you don't want to loop.
That is, memset(myarr, 5, arrsize); in order to fill it with all 5's. Beware of implicit conversion to unsigned char.
SYNOPSIS
#include <string.h>
void *
memset(void *b, int c, size_t len);
DESCRIPTION
The memset() function writes len bytes of value c (converted to an
unsigned char) to the byte string b.
And if the vector is large, and you need it to go fast and you are using gcc, then :
Code generation of block move (memcpy)
and block set (memset) was rewritten.
GCC can now pick the best algorithm
(loop, unrolled loop, instruction with
rep prefix or a library call) based on
the size of the block being copied and
the CPU being optimized for.
I want to define an integer variable in C/C++ such that my integer can store 10 bytes of data or may be a x bytes of data as defined by me in the program.
for now..!
I tried the
int *ptr;
ptr = (int *)malloc(10);
code. Now if I'm finding the sizeof ptr, it is showing as 4 and not 10. Why?
C and C++ compilers implement several sizes of integer (typically 1, 2, 4, and 8 bytes {8, 16, 32, and 64 bits}), but without some helper code to preform arithmetic operations you can't really make arbitrary sized integers.
The declarations you did:
int *ptr;
ptr = (int *)malloc(10);
Made what is probably a broken array of integers. Broken because unless you are on a system where (10 % sizeof(int) ) == 0) then you have extra bytes at the end which can't be used to store an entire integer.
There are several big number Class libraries you should be able to locate for C++ which do implement many of the operations you may want preform on your 10 byte (80 bit) integers. With C you would have to do operation as function calls because it lacks operator overloading.
Your sizeof(ptr) evaluated to 4 because you are using a machine that uses 4 byte pointers (a 32 bit system). sizeof tells you nothing about the size of the data that a pointer points to. The only place where this should get tricky is when you use sizeof on an array's name which is different from using it on a pointer. I mention this because arrays names and pointers share so many similarities.
Because on you machine, size of a pointer is 4 byte. Please note that type of the variable ptr is int *. You cannot get complete allocated size by sizeof operator if you malloc or new the memory, because sizeof is a compile time operator, meaning that at compile time the value is evaluated.
It is showing 4 bytes because a pointer on your platform is 4 bytes. The block of memory the pointer addresses may be of any arbitrary size, in your case it is 10 bytes. You need to create a data structure if you need to track that:
struct VariableInteger
{
int *ptr;
size_t size;
};
Also, using an int type for your ptr variable doesn't mean the language will allow you to do arithmetic operations on anything of a size different than the size of int on your platform.
Because the size of the pointer is 4. Try something like:
typedef struct
{
int a[10];
} big_int_t;
big_int_t x;
printf("%d\n", sizeof(x));
Note also that an int is typically not 1 byte in size, so this will probably print 20 or 40, depending on your platform.
Integers in C++ are of a fixed size. Do you mean an array of integers? As for sizeof, the way you are using it, it tells you that your pointer is four bytes in size. It doesn't tell you the size of a dynamically allocated block.
Few or no compilers support 10-byte integer arithmetic. If you want to use integers bigger than the values specified in <limits.h>, you'll need to either find a library with support for big integers or make your own class which defines the mathematical operators.
I believe what you're looking for is known as "Arbitrary-precision arithmetic". It allows you to have numbers of any size and any number of decimals. Instead of using fixed-size assembly level math functions, these libraries are coded to do math how one would do them on paper.
Here's a link to a list of arbitrary-precision arithmetic libraries in a few different languages, compliments of Wikipedia: link.