5
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
using namespace std;

int color[1001][1001];

int main() {
    int i, j;
    memset(color, 1, sizeof(color[0][0]) * 2 * 2);
    for(i = 0; i < 4; i++) {
        for(j = 0; j < 4; j++) {
            printf("%d ", color[i][j]);
        }
        printf("\n");
    }
    printf("\n");

    return 0;
}

output:

16843009 16843009 16843009 16843009 
0 0 0 0 
0 0 0 0 
0 0 0 0 

Why isn't it assigning 1? Why didn't it print 1 instead of 16843009 ? How can i assign integer 1?

But if i write memset(color, 0, sizeof(color[0][0]) * 2 * 2); Then the output:

0 0 0 0 
0 0 0 0 
0 0 0 0 
0 0 0 0 

Why is this?

Any answer will be highly appreciated. Thanks in advance.

cola
  • 12,198
  • 36
  • 105
  • 165

4 Answers4

15

Because memset sets each byte to 1.

So if int is four bytes (32 bits, what it most commonly is) then you set each element to 0x01010101.

Read more in this memset reference page.


For a more C++-ish solution I suggest using std::fill:

std::fill(&color[0][0], &color[0][0] + sizeof(color) / sizeof(color[0][0]), 1);

That will set all elements to 1.


A third option is to use std::array instead, and its fill member function:

std::array<std::array<int, 1001>, 1001> color;
...
for (auto& inner : color)
{
    inner.fill(1);
}
Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
  • 4
    This is incorrect use of fill. The iterator you pass as the first argument must have its value writable by dereferencing it, however dereferencing `color` gives another array. This causes a compilation error. Also `color + sizeof(color)/sizeof(color[0][0])` causes undefined behaviour by forming an out-of-bounds pointer. – M.M Mar 07 '16 at 08:37
  • @M.M I always thought a pointer right behind the last element is well-defined, only dereferencing it is not. Iterators work this way, AFAIK. – cadaniluk Mar 07 '16 at 08:44
  • 1
    @M.M Just for confirmation, it should be `std::fill(&color[0][0], &color[0][0] + sizeof(color) / sizeof(color[0][0]), 1);`, is it right? – songyuanyao Mar 07 '16 at 08:46
  • 1
    @cad , Yes, forming pointer to one-past-the-last element is explicitely allowed. – Revolver_Ocelot Mar 07 '16 at 08:52
  • @cad That's true . `sizeof(color)/sizeof(color[0])` would lead to such a pointer. However the actual code divides by a smaller quantity than `sizeof(color[0])`. – M.M Mar 07 '16 at 09:04
  • @songyuanyao arguably that version also breaks the rule about `+` adding to the same array, because it goes off the end of `color[0]`. I would write `(int *)&color, (int *)&color + sizeof(color)/sizeof(int)` . Actually I would avoid all this entirely by using either a 1-d array, or a nested ranged-based `for` – M.M Mar 07 '16 at 09:06
  • @M.M `&color[0][0]` is always equivalent with `(int *)&color`, isn't it? Might break in some cases? – songyuanyao Mar 07 '16 at 09:12
  • @songyuanyao Both result in the same address, but they are not really the same and should not be treated as such. See e.g. [this recent answer of mine](http://stackoverflow.com/questions/35771298/pointer-and-address-to-that-pointer-lead-to-the-same-thing/35771465#35771465) for details. – Some programmer dude Mar 07 '16 at 09:14
  • But if i write `memset(color, 0, sizeof(color[0][0]) * 2 * 2);` Then the output is zero. Why? I have edited the original question. – cola Mar 07 '16 at 09:17
  • @M.M & JoachimPileborg, I see, thanks. – songyuanyao Mar 07 '16 at 09:17
  • @shibly Because then you initialize each byte to zero, i.e. an `int` would be `0x00000000`. – Some programmer dude Mar 07 '16 at 09:18
  • @JoachimPileborg, zero = null? The value of null = zero. – cola Mar 07 '16 at 09:22
  • @shibly A null pointer doesn't *have* to be equal to zero. If needed, the compiler will translate `0` to the correct null-pointer value when dealing with pointers. To be safe use `0` for the actual *value* zero, and `nullptr` for pointers. – Some programmer dude Mar 07 '16 at 09:24
  • @JoachimPileborg, not null pointer, null character. – cola Mar 07 '16 at 09:28
  • @JoachimPileborg, 0x00000000 = null character(ascii), isn't it? – cola Mar 07 '16 at 09:36
  • @shibly Ah then yes, the null *character* is zero. And no, a single character is usually only a single byte, so only `0x00` (or `'\0'`) – Some programmer dude Mar 07 '16 at 09:37
15

Manpage :

#include <string.h>
void *memset(void *s, int c, size_t n)

The memset() function fills the first n bytes of the memory area pointed to by s with the constant byte c.

Therefore, memset can't be used to initialize int array with 1 because if int is represented by 4 bytes, then it will initialize each bytes with 1.
16843009 is equivalent to 0x01010101. Each of 4 bytes are initialized with 01.
Using memset, an array of int can only be initialised with 0 or -1 because 0 and -1 both have all bits 0 and 1 respectively in two's complement binary representation regardless of the size of int data type.

haccks
  • 104,019
  • 25
  • 176
  • 264
  • But if i write `memset(color, 0, sizeof(color[0][0]) * 2 * 2);` Then the output is zero. Why? I have edited the original question. – cola Mar 07 '16 at 09:12
  • @shibly because an integer where all the individual bytes are zero, is also the value zero of that integer. (And since your array is declared at file scope (A "global" variable), the entire array is anyway initialized with zero values) – nos Mar 07 '16 at 09:42
  • @nos, 0x00000000 = null character(ascii), isn't it? – cola Mar 07 '16 at 09:45
  • @shibly If you interpret the value as ascii, yes. Though normally you'd use a char to represent ascii values. – nos Mar 07 '16 at 09:51
  • @shibly; I already explained it in the answer. Note that `char` is of only `1` byte. So `0x00` represents a null character in hexadecimal. – haccks Mar 07 '16 at 10:26
  • @haccks `16843009` is equivalent to `0x01010101` I'm wondering why you don't take the value of `Binary` but take the number of `hexadecimal 16843009 = 0x01010101` ? – Oosutsuke Sep 06 '21 at 21:05
  • @Oosutsuke; Sorry, I didn't get your question. – haccks Sep 06 '21 at 23:50
7

memset() will write the specified value to every byte in the range, so if int is 4-byte long, the value will be 0x01010101, not 1.

To assign integer 1, assign integer 1.

for (i = 0; i < (int)(sizeof(color)/sizeof(*color)); i++) {
    for (j = 0; j < (int)(sizeof(color[i])/sizeof(*color[i])); j++) {
        color[i][j] = 1;
    }
}
MikeCAT
  • 73,922
  • 11
  • 45
  • 70
2

memset() is setting your memory 8-Bit aligned to the value you chose, which is 1. But for your array color[][] you declared the 32-Bit datatype int, which has four bytes. So what memset() does is to set each of this four bytes to the value 1.

This also explains your result: 16843009d = 0x01010101.

If you have a look at your memory:

memset() to 1:

//.color[0][0].||..color[0][1]...||..color[0][2]...||..color[0][3]..
01  01  01  01    01  01  01  01    01  01  01  01    01  01  01  01
//.color[1][0].||..color[1][1]...||..color[1][2]...||..color[1][3]..
00  00  00  00    00  00  00  00    00  00  00  00    00  00  00  00
//.color[2][0].||..color[2][1]...||..color[2][2]...||..color[2][3]..
00  00  00  00    00  00  00  00    00  00  00  00    00  00  00  00 
//.color[3][0].||..color[3][1]...||..color[3][2]...||..color[3][3]..
00  00  00  00    00  00  00  00    00  00  00  00    00  00  00  00 

memset() to 0:

//.color[0][0].||..color[0][1]...||..color[0][2]...||..color[0][3]..
00  00  00  00    00  00  00  00    00  00  00  00    00  00  00  00
//.color[1][0].||..color[1][1]...||..color[1][2]...||..color[1][3]..
00  00  00  00    00  00  00  00    00  00  00  00    00  00  00  00
//.color[2][0].||..color[2][1]...||..color[2][2]...||..color[2][3]..
00  00  00  00    00  00  00  00    00  00  00  00    00  00  00  00 
//.color[3][0].||..color[3][1]...||..color[3][2]...||..color[3][3]..
00  00  00  00    00  00  00  00    00  00  00  00    00  00  00  00 

If you are calling memset() with the value 0 then you get a 32 Bit int value = 0x00000000 = 0d.

Note:

If you want to set your whole array to a value use the following line:
memset(color, 1, sizeof(color));

Then your array looks the following:

1010101 1010101 1010101 1010101 
1010101 1010101 1010101 1010101 
1010101 1010101 1010101 1010101 
1010101 1010101 1010101 1010101 

View the code here[^].

Frodo
  • 749
  • 11
  • 23
  • But if i write `memset(color, 0, sizeof(color[0][0]) * 2 * 2);` Then the output is zero. Why? I have edited the original question. – cola Mar 07 '16 at 09:16