分配器感知'的std :: array`式集装箱?(Allocator-aware `std

2019-09-30 03:04发布

我正在写一些代码,处理密码的秘密,我创建了一个自定义的ZeroedMemory实施std::pmr::memory_resource它处理的释放进行消毒记忆和使用,你必须使用,以防止eliding远优化编译器的魔力封装操作。 其想法是避免专门std::array ,因为缺乏虚析构函数意味着破坏型擦除之后会导致没有被消毒,以释放存储器。

不幸的是,我认识到事后说std::array不是AllocatorAwareContainer 。 我std::pmr::polymorphic_allocator的做法是有点误导,因为显然没有空间在std::array的指针存储到一个特定的分配情况。 不过,我不能完全理解为什么分配器为它std::allocator_traits<A>::is_always_equal::value == true不会允许,我可以很容易地重新实现我的解决方案作为一种通用的Allocator ,而不是更容易-to-使用std::pmr::memory_resource ...

现在,我可以正常只需使用一个std::pmr::vector ,而不是,而是的不错的功能,一个std::array是数组的长度是类型的一部分。 如果我处理一个32字节的密钥,例如,我没有做的运行时检查,以确保该std::array<uint8_t, 32>参数人传递给我的功能,事实上,正确的长度。 事实上,那些垂下很好到const std::span<uint8_t, 32>这极大地简化了需要,因为它们使去到基本上任何来源的处理任意的存储块免与C语言代码进行互操作写入功能。

讽刺的是, std::tuple发生分配器......但我不敢想象能够处理32字节需要的typedef std::tuple<uint8_t, uint8_t, uint8_t, uint8_t, ...>

所以:有保持固定数量的均匀类型的物品的,一拉任何标准肥胖型类型std::array ,但是分配器感知(和优选地存储在一个continguous区域中的物品,所以它可以是向下转换到一个std::span )?

Answer 1:

你需要为了从编译器和操作系统这两个合作这种计划的工作。 P1315是解决事情的编译器/语言方面的建议。 至于操作系统,你必须确保内存从来没有分页到磁盘等,为了使这种真正零内存。



Answer 2:

这听起来像一个XY问题。 你似乎滥用分配器。 分配器用于处理的运行时存储器分配和解除分配,而不是钩堆栈存储器。 你所要做的 - 使用后归零的记忆 - 真的应该有析构函数来完成。 您可能需要写一个类Key为这样的:

class Key {
public:
    // ...
    ~Key()
    {
        secure_clear(*this); // for illustration
    }
    // ...
private:
    std::array<std::uint8_t, 32> key;
};

您可以轻松地实现迭代器和跨度的支持。 而你并不需要分配器玩。

如果你想减少样板代码,使新的类自动迭代器/ SPAN友好,使用继承:

class Key :public std::array<std::uint8_t, 32> {
public:
    // ...
    ~Key()
    {
        secure_clear(*this); // for illustration
    }
    // ...
};


文章来源: Allocator-aware `std::array`-style container?