Reputation: 51
I have used an array as dt[100]; then,i have initialize the values like memset(dt,63,sizeof(dt)); then i have seen the value assigned in those array like 4557430888798830399.can i have the explanation?
#include <bits/stdc++.h>
#define ll long long int
using namespace std;
ll dt[100];
int main()
{
memset(dt,63,sizeof(dt));
cout<<dt[0]<<endl;
}
Upvotes: 0
Views: 961
Reputation: 26476
well, answers here are almost right.
the most flexible, correct solution is to use std::fill
with std::begin
+ std::end
std::fill(std::begin(dt),std::end(dt),63);
std::fill
instead of memset
, because std::fill
is aware of objects and will call the correct assignment operation. memset
knows only what a byte is (C vs C++).memset
fills bytes, std::fill
fills any variable with any sizestd::fill
will call memset
or memmove
anyway if the variable size equals a byte size (yes, the standard library is not that stupid as we might think it is..)std::begin
+ std::end
"know" the size of a C array, so no erroneous stuff like arr , arr + 100
which breaks the moment the array size is changedstd::begin
+ std::end
work with C arrays and any C++ container which supplies begin()
and end()
methods (vector , deque , list
etc). so without putting any effort, the code is general (the sizeof
trick will not work for std::vector
, for example).as for why does the long long
has such weird value, is because memset
fills every byte and not every long long
.
so, assuming each long long
is 8 bytes, memory wise, the long long
after the memset
looks like
byte
|
V
[63][63][63][63][63][63][63][63]
^ ^
| long long |
and in binary :
0011111100111111001111110011111100111111001111110011111100111111
//63 == 00111111, 8 bytes of each
which is :
4557430888798830399
(I deliberately did not go into endianess details in order not to complicate the subject too much)
Upvotes: 10
Reputation: 9406
As others have already pointed out, the memset
copies 63 to each byte of the array. That is why your numbers are not what you expect. You should also try to avoid memset
and memcpy
in C++ and only use it when you are sure that the objects being copied are PODs or standard-layout types. Copying general C++ objects can be very problematic, and memsetting objects is a recipe for disaster.
An alternative to std::fill
, which is fully ok, is to not use plain C arrays at all. Instead, use either std::vector<long long>
or std::array<long long, N>
.
To create a vector of 10 elements with value 63:
std::vector<long long> v(10, 63);
To create a statically allocated array of 10 elements with value 63
std::array<long, long, 10> a;
a.fill(63);
PS: try not to use #define
for typedefs or constants or inline functions. C++ has type-safe replacements for most C constructs.
Upvotes: 2
Reputation: 10316
As per above answers, byte-level filling is the reason you get what you get. As an alternative to above suggestions, you could use this:
std::fill(dt, dt+100, 63);
The advantage here is that this is more likely to be optimized and thus quicker than manually looping over the memory (e.g. it could use SIMD vector instructions on x86_64 architectures)
Upvotes: 4
Reputation: 30126
As mentioned in a comment by @Michael Burr, function memset
sets the value of each char
in the given block of memory, while each cell in your array is long long
.
Alternative solutions:
for (size_t i=0; i<sizeof(dt)/sizeof(*dt); i++)
dt[i] = 63;
for (auto& n : dt)
n = 63;
Upvotes: 1