underdog
underdog

Reputation: 49

Why does memset not store all values similarly in 2D array?

I have a 2D array set as

long long arr[500][500]

Running this main function, I get different values for m=-1 and m=-3:

int main(){
    memset(arr,m,sizeof(arr));
    for(int i=0;i<10;i++)
        cout<<arr[i][i]<<'\n';
    return 0;
}

for m=-3: it prints -144680345676153347 20 times, for m=-1, it is -1, as it should be. What is the cause for this?

#include<iostream>
#include<cstring>
using namespace std;
using ll=long long;

ll dp[501][501];

int main(){
    //ios_base::sync_with_stdio(0);
    //cin.tie(0);
    //int n;
    //cin>>n;
    memset(dp,-3,sizeof(dp));
    for (int i = 0; i < 20; i++) {
        cout<<dp[i][i]<<'\n';
    }
    return 0;
}

Upvotes: -1

Views: 121

Answers (2)

paxdiablo
paxdiablo

Reputation: 881093

It's because memset sets individual bytes in memory, not integers. I'll just use the term "integer" below when referring to your specific 64-bit 2s-complement long long type(1), since the same behaviour applies to all 2s-complement integer types.

Using -1 works because it stores 0xff in every byte and it just happens that the integer value 0xffffffffffffffff is also -1.

However, -3 stores 0xfd and the value 0xfdfdfdfdfdfdfdfd is not -3 (that would be 0xfffffffffffffffd instead).

If you convert the repeating-0xfd value into an integer, you'll get what you're seeing: -144,680,345,676,153,347`.

Unless you know that a repeated byte pattern generates the same value as an integer (for example, 0x00 or 0xff), you're probably better off using a loop to set the values (the same way you print them), something like:

#include <iostream>

#define DIM 500
long long arr[DIM][DIM];

int main(){
    for(size_t dim1 = 0; dim1 < DIM; ++dim1) {
        for(size_t dim2 = 0; dim2 < DIM; ++dim2) {
            arr[dim1][dim2] = -3;
        }
    }

    for(size_t idx = 0; idx < 3; ++idx) {
        std::cout << arr[idx][idx] << '\n';
    }

    return 0;
}

This generates, as desired:

-3
-3
-3

(1) It's reasonable to assume your system has a 64-bit long long type because the 32-bit 2s-complement value for 0xfdfdfdfd is -33,686,019, which you are not seeing.

Upvotes: 6

Chris
Chris

Reputation: 36440

As an addendum to the answer from paxdiablo, I would suggest using std::fill as you are using C++.

E.g.

#include <iostream>
#include <algorithm>

int arr[10][10];

int main() { 
    for (auto &row : arr) {
        std::fill(std::begin(row), std::end(row), -3);
    }

    for (auto &row : arr) {
        for (auto &cell : row) {
            std::cout << cell << " "; 
        }
        std::cout << "\n";
    }
}

Output:

-3 -3 -3 -3 -3 -3 -3 -3 -3 -3 
-3 -3 -3 -3 -3 -3 -3 -3 -3 -3 
-3 -3 -3 -3 -3 -3 -3 -3 -3 -3 
-3 -3 -3 -3 -3 -3 -3 -3 -3 -3 
-3 -3 -3 -3 -3 -3 -3 -3 -3 -3 
-3 -3 -3 -3 -3 -3 -3 -3 -3 -3 
-3 -3 -3 -3 -3 -3 -3 -3 -3 -3 
-3 -3 -3 -3 -3 -3 -3 -3 -3 -3 
-3 -3 -3 -3 -3 -3 -3 -3 -3 -3 
-3 -3 -3 -3 -3 -3 -3 -3 -3 -3 

Upvotes: 3

Related Questions