c++ - 使用 T 写入 uint8_t

标签 c++ arrays

我有一个 std::uint8_t * bytes 成员 (ByteArray#bytes),但不能将 T 值放在它正确。到目前为止,我只测试了在索引 0 处写入 int = 259,然后我读取它并得到 3 作为输出。

http://rextester.com/HKU93771

ByteArray.hh

/*
 * Copyright (c) 2017 Uncloud Group. All Rights Reserved.
 *
 * See ~/COPYRIGHT.md.
 */

#ifndef mutils_ByteArray_hh
#define mutils_ByteArray_hh

#include <cstddef>
#include <cstdint>
#include <cstdlib>

// (Endianness is detected at compile time, so...)
// (careful.)

#if __BYTE_ORDER == __LITTLE_ENDIAN
    #define MUTILS_LE
#endif

static std::uint8_t * reversing;
static std::uint8_t i;
static std::uint8_t j;

namespace mutils
{
    // Dynamically-sized array of bytes.

    class ByteArray
    {
    public:
        // (Creates an empty ByteArray.)

        ByteArray() { SetLength(0); }

        ByteArray(std::size_t length)
        {
            bytes = nullptr;
            SetLength(length);
        }

        ~ByteArray()
        {
            std::free(bytes);
        }

        // Read little-endian value.

        template<typename T>
        inline T
        ReadLE(std::size_t index)
        {
            std::uint8_t s = bytes[index];

            #ifdef MUTILS_LE
                return T(s);
            #else
                return reverse<T>(&s);
            #endif
        }

        // Write value using little-endianness.
        // Note: No out-of-bounds check is done.

        template<typename T>
        inline void
        WriteLE(std::size_t index, T value)
        {
            #ifndef MUTILS_LE
                value = reverse(&value);
            #endif
            ((T&) bytes[index]) = value;
        }

        inline auto
        GetLength() { return length; }

        void
        SetLength(std::size_t len);

//      ByteArray
//      SliceView(std::size_t start_v, std::size_t end_v);

    private:
        std::uint8_t * bytes;
        std::size_t length;

        // Reverse the byte-order of a value.

        template<typename T>
        T
        reverse(std::uint8_t * value)
        {
            for (i = 0, j = sizeof(T); (--j) >= sizeof(T); ++i)
                reversing[j] = value[i];

            return T(*reversing);
        }
    };

} // namespace mutils

#endif // mutils_ByteArray_hh

ByteArray.cc

/*
 * Copyright (c) 2017 Uncloud Group. All Rights Reserved.
 *
 * See ~/COPYRIGHT.md.
 */

#include <mutils/ByteArray.hh>
#include <cstddef>
#include <cstdint>
#include <cstdlib>

// Updates the array length.

void
mutils::ByteArray::SetLength(std::size_t len)
{
    if (len == 0) 
         bytes = nullptr;
    else bytes = (std::uint8_t *) realloc(bytes, len);

    length = len;
}

测试

#include <iostream>

int main()
{
    mutils::ByteArray b(4);
    b.WriteLE<int>(0, 259);
    std::cout << b.ReadLE<int>(0) << "\r\n";
    return 0;
}

最佳答案

这就是 memcpy 的用途。

T t写入bytes:

memcpy(bytes + index, &t, sizeof t);

bytes中读取T

T result;
memcpy(&result, bytes + index, sizeof result);
return result;

如果字节顺序错误,则在字节数组中反转字节。更改 T 类型变量内的字节顺序可能会暂时创建非法表示并触发处理器错误。

您在 WriteLE 中使用的指针转换等其他方法也可能触发处理器错误,例如由于对齐。

只需使用memcpy

(即使是 std::copystd::copy_n 在涉及到严格的别名和按位图像时也有点问题,3.9 节中的标准使用 std::memcpy 正是为了这个目的)

关于c++ - 使用 T 写入 uint8_t,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46548370/

相关文章:

java - 标记化字节数组

C++ Final 或 Sealed

c++ - 我如何将 std::get 作为参数传递给模板函数?

c++ - Qt Creator 中“未找到有效工具包”

c++ - 使用 Kasper Peeters 的 Tree.hh 库避免在节点中添加重复的子节点

javascript - 使用 unshift() 使用 javascript 将表单输入添加到数组

javascript - React axios 发送多张图片表单数据

php - CodeIgniter:从表单数组获取数据到帖子数组

java - 将对象数组传递给java中的方法

c++ - 使用迭代器打印列表