ilovecake71
ilovecake71

Reputation: 13

Array storage in memory

I am reading a stream of chars and I need them straight as uint64_t values. I used the following approach. But it seems that the array is stored in backward order. However the memory locations are in order when I output their addresses. Sorry if this is a too dumb question. I am struggling to figure out my basic memory knowledge.

#include <iostream>

int main() {
    unsigned char ar[8] = {1, 0, 0, 0, 0, 0, 0, 0};
    uint64_t num = *((uint64_t*)ar);
    std::cout << num << std::endl;

    for(size_t i = 0; i < 8; i++) {
        std::printf("%lu %x\n", i, &ar[i]);
    }
}

Following is the output

1
0 ffffcc08
1 ffffcc09
2 ffffcc0a
3 ffffcc0b
4 ffffcc0c
5 ffffcc0d
6 ffffcc0e
7 ffffcc0f

I expected the result of num to be 2^56.

Upvotes: 1

Views: 111

Answers (1)

Oblivion
Oblivion

Reputation: 7374

The problem is the endian, your system is little endian and you read the uint64_t like you are in a big endian system. there is one compile time solution without branching in c++20:

you can use std::endian to find the endian at compile time and use if constexpr to decide how your functions work.

#include<iostream>
#include <type_traits>

template <typename T>
void print()
{
    constexpr bool is_little_endian = (std::endian::native == std::endian::little); 
    if constexpr (is_little_endian) {
        unsigned char ar[8] = {0, 0, 0, 0, 0, 0, 0, 1};
        T num = *((T*)ar);
        std::cout << num << std::endl;
    } else {
        unsigned char ar[8] = {1, 0, 0, 0, 0, 0, 0, 0};
        T num = *((T*)ar);
        std::cout << num << std::endl;
    }
}

int main()
{
    print<uint64_t>();
}

Output

72057594037927936

Live

Upvotes: 1

Related Questions