memset does not work with large numbers

2

I have the following simple code:

#include <bits/stdc++.h>
#define oo 0xffffff
using namespace std;

int main()
{
    int v[10];
    memset(v, oo, sizeof(v));
    for(int i = 0; i < 10; i++)
        cout << v[i] << endl;
   return 0;
}

It is assumed that the memset should set all the values to 0xffffff, but when I print the fix, this comes out:

$g++ -std=c++11 -o main *.cpp
$main
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1

However, I have not had any problems when the values to be set are 0 or -1. Why is it?

Thank you very much!

    
asked by Genarito 30.10.2017 в 18:50
source

1 answer

4

The fault of this behavior is memset , whose signature is:

void* memset( void* dest, int ch, std::size_t count );

This function converts the value passed as second parameter to char and copies it as many times as indicated by the third parameter in each of the characters of the object pointed to by the first parameter.

Thus, the value% co_of% of integer type ( 0xffffff ) is converted to type character ( int ). In 32bit architectures an integer can contain 2 32 values † whereas a character can usually contain 2 8 values ‡ When passing a larger type to a smaller one, truncation occurs so that we change the value from char to value 0xffffff . The value 0xff in a type character with sign ※ ( 0xff ) corresponds to char so copy that value in the pointer pointed by -1 to reach dest copies.

  

What I do not understand is why if I assign the values with a for instead of with memset it works as an unsigned integer.

When you copy in a count loop instead of using for there are no type transformations and you assign the value memset (16.777.215 in type 0xffffff ) not the value int ( 0xff in type -1 ).

  

ffffff is 16777215, why would 4294967295 appear if it is not the actual value of the hexadecimal being allocated?

char (six f) is 16,777,215 and 0xffffff (eight f) is 4,294,967,295. I was wrong to read your question, you're right, 0xffffffff will not appear unless you assign 4294967295

  

I tried changing 0xffffffff by copy and it worked.

Another failure of mine, very well seen:)

Previous answer, not relevant . I keep it so that the comments continue to make sense.

The code is working perfectly. The value fill in a signed number is 0xffffffff , to understand why I recommend reading this thread .

If you change -1 by int v[10]; you will get:

4294967295
4294967295
4294967295
4294967295
4294967295
4294967295
4294967295
4294967295
4294967295
4294967295

But in C ++ you should not be using unsigned v[10]; , use memset :

copy(begin(v), end(v), oo);

Although if you wanted to fill std::copy with v you could do it at compile time instead of at run time:

int v[10] { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff};

† Four thousand two hundred ninety-four million nine hundred sixty-seven thousand two hundred and ninety-six different values.

‡ Two hundred and fifty-six different values.

※ The type 0xffffffff may or may not have a sign, it is platform dependent.

    
answered by 30.10.2017 / 19:15
source