C++ STL容器使用的归零内存

C++ STL容器使用的归零内存,c++,C++,我希望使用STL容器(加上std::basic_string)在内存中临时存储密钥或密码,并希望在完成时将内存归零 我最初计划在自定义分配器上使用参数化的STL容器,该分配器将allocator::deallocate中的内存归零,但我假定允许容器使用不来自指定分配器的内存。例如,std::vector或std::string包含用于小分配的固定大小数组成员似乎是合理的 我是否有理由担心,我是否应该(叹气)编写自己的容器?我将使用std::vector和一个自定义分配器来执行零运算。根据at的答

我希望使用STL容器(加上
std::basic_string
)在内存中临时存储密钥或密码,并希望在完成时将内存归零

我最初计划在自定义分配器上使用参数化的STL容器,该分配器将
allocator::deallocate
中的内存归零,但我假定允许容器使用不来自指定分配器的内存。例如,
std::vector
std::string
包含用于小分配的固定大小数组成员似乎是合理的


我是否有理由担心,我是否应该(叹气)编写自己的容器?

我将使用
std::vector
和一个自定义分配器来执行零运算。根据at的答案,它不能使用小缓冲区优化,因此,使用自定义分配器,您应该是安全的


如果您更进一步,使用该分配器分配向量,然后使用智能指针确保其正确释放(或手动执行),甚至向量的内部内容(如大小)将被清除。

您可以通过使用原始内存分配字符串/向量并放置新的位置来完成此操作,完成后,调用析构函数、零内存并释放原始内存。

使用自定义字符串类将析构函数中的内存缓冲区归零

class zeroed_string : public std::string
{
public:
    ~zeroed_string()
    {
        for (int i = 0; i < size(); ++i)
            (*this)[i] = 0;
    }
// ...
};
class zeroed_string:public std::string
{
公众:
~zeroed_string()
{
对于(int i=0;i
我不明白的是,为什么不使用vector,在让它超出范围之前,只需做一个memset(myVec,0x00,myVec.size())?对于
std::vector
来说,您必须跳出火焰环以满足异常要求,并且仍然将数据存储在vector对象本身中。对于
std::string
,在对象中存储数据不仅是可能的,而且是相当常见的。@AntonRoth:因为如果有人调用
std::vector::resize
std::vector::push_back
并导致
std::vector
分配一个新的内存块并复制现有的缓冲区会发生什么?是的,我在先前的回答中写道,我删除了,因为我对这个问题不太确定,你可以分配比以往任何时候都需要的更多的内存,并将其归零。还是使用的内存很重要?我是不是遗漏了什么?将清理作为存储对象的责任而不是容器的责任是否更有意义?那么,就让容器存储一个类项,其析构函数在其自身之后进行清理?当向量调整大小时,不要复制构造函数,然后调用所有的析构函数…?100%正确且完全合理的方法!但不可重用,并且绕过STL代替核心C++操作符和内存黑客。通过编写自定义分配器,您所编写的所有内容都可以很好地包装起来,请参见DateS'sanswer@quetzalcoatl:它使用stl,我的意思是将字符串/向量对象放在原始内存中。不,您必须使用分配器。向量/字符串分配的堆内存不会受到对象内存清零的影响。即使显式地将向量中的值归零,向量的大小调整操作仍可能留下副本。@Eclipse:我猜想Dani的意思是将placement new与自定义分配器结合使用。@Quetzalcatl:是的,如果同时使用自定义分配器和placement new,我不认为std::string是用来作为基类的,否则它会有虚拟析构函数。顺便说一句,您的答案与-4 bellow相同。正如我在另一个(现已删除)答案中提到的,如果
std::string
曾经被调整过大小,并且需要分配一个新的内存块,那么这将不起作用。对该答案的其他评论也指出,它不适用于COW实现。@Bцццћ如果您打算以多态方式使用它,则是正确的,但在本例中,您不是。“我认为人们在这一点上太过偏执了。”“jamesdlin,我的答案是最简单的方法,但建议仍然有效——使用一个自定义的string类来强制实现您所需的安全性。如果
std::string
不可用,请从头开始编写一个。这是否经过测试?原则上,编译器可以优化这个循环,因为它(可能)没有可观察的行为。