读取内存的特定地址并按所需类型解释

时间:2018-11-26 17:25:30

标签: c++

假设我有一个float someArray[10]数组,但我已经为其所有元素分配了值。我知道someArray有40个字节分配的内存,因为每个浮点数都有4个字节。

现在,我想从头开始用two bytetwo byte读取这40个字节的内存,并将它们解释为unit16_t,这样我将拥有unit16_t intArray[20]的数组。我不想使用union

我也阅读了以下问题,但没有帮助:

read memory reinterpret

2 个答案:

答案 0 :(得分:3)

这是非常棘手的,非常底层的东西。您绝对确定无法以其他任何方式解决此问题吗?您是否考虑了字节序?你是?你有?好吧。

C ++不允许您在内存中采用连续区域并将其解释为所需的任何内容。几乎唯一允许您做的是将指向属于单个数组的连续内存块的开头的指针解释为char*unsigned char*或由于C ++ 17也std::byte*(请参阅严格的别名规则,请参见标准中的[basic.lval]部分,对于C ++ 17,则为§6.10(8))。从本质上讲,这意味着您可以将数组解释为字节序列。就是这样,但是足以复制内存。这就是您在不相关的类型之间进行转换的方式。

使用C型数组(它们容易出错,因此请尽量避免):

#include <cstddef>
#include <cstdint>
#include <cstring>

int main()
{
    constexpr std::size_t item_count = 10;

    float float_array[item_count] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
    std::uint16_t int_array[item_count * (sizeof(float) / sizeof(uint16_t))];

    std::memcpy(
            reinterpret_cast<char*>(int_array),
            reinterpret_cast<char*>(float_array),
            item_count * sizeof(float));
}

或使用std::array

#include <array>
#include <cstddef>
#include <cstdint>
#include <cstring>

int main()
{
    std::array<float, 10> float_array = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
    std::array<std::uint16_t, float_array.size() * (sizeof(float) / sizeof(uint16_t))> int_array;

    std::memcpy(
            reinterpret_cast<char*>(int_array.data()),
            reinterpret_cast<char*>(float_array.data()),
            float_array.size() * sizeof(float));
}

答案 1 :(得分:-3)

float someArray[10]{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
void * void_ptr_to_array  = static_cast<void*>(someArray);
uint16_t * ptr_to_array = static_cast<uint16_t*>(void_ptr_to_array);

for(int i = 0; i < 20; ++i)
    std::cout << ptr_to_array[i] << '\n';

输出

0
16256
0
16384
0
16448
0
16512
0
16544
0
16576
0
16608
0
16640
0
16656
0
16672