Hacking a SecureString based on std::basic_string for C++ Inspired by reading &quot;How-to write a password-safe class?&quot;, I tried some clever (or dumb-fool) hack to create a widely-useable secure string using the std::basic_string-template, which does not need to be explicitly securely erased itself.
At least gcc and clang seem not to choke on it (coliru):
#include &lt;string&gt;
namespace my_secure {
void SecureZeroMemory(void* p, std::size_t n) {
    for(volatile char* x = static_cast&lt;char*&gt;(p); n; --n)
        *x++ = 0;
}

// Minimal allocator zeroing on deallocation
template &lt;typename T&gt; struct secure_allocator {
    using value_type = T;

    secure_allocator() = default;
    template &lt;class U&gt; secure_allocator(const secure_allocator&lt;U&gt;&amp;) {}

    T* allocate(std::size_t n) { return new T[n]; }
    void deallocate(T* p, std::size_t n) {
        SecureZeroMemory(p, n * sizeof *p);
        delete [] p;
    }
};

template &lt;typename T, typename U&gt;
inline bool operator== (const secure_allocator&lt;T&gt;&amp;, const secure_allocator&lt;U&gt;&amp;) {
    return true;
}
template &lt;typename T, typename U&gt;
inline bool operator!= (const secure_allocator&lt;T&gt;&amp;, const secure_allocator&lt;U&gt;&amp;) {
    return false;
}

using secure_string = std::basic_string&lt;char, std::char_traits&lt;char&gt;,
    secure_allocator&lt;char&gt;&gt;;
}

namespace std {
// Zero the strings own memory on destruction
template&lt;&gt; my_secure::secure_string::~basic_string() {
    using X =std::basic_string&lt;char, std::char_traits&lt;char&gt;,
        my_secure::secure_allocator&lt;float&gt;&gt;;
    ((X*)this)-&gt;~X();
    my_secure::SecureZeroMemory(this, sizeof *this);
}
}

And a short program using it to do nothing much:
//#include &quot;my_secure.h&quot;
using my_secure::secure_string;
#include &lt;iostream&gt;

int main() {
    secure_string s = &quot;Hello World!&quot;;
    std::cout &lt;&lt; s &lt;&lt; '\n';
}

Some specific concerns:

How badly did I break the standard?

Does the fact that one of the template-arguments is my own type heal the fact that I added my own explicit specialization to ::std?
Are the two types actually guaranteed to be similar enough that my bait-and-switch in the destructor is ok?


Is there any actual implementation where the liberties I took with the standard will come back to haunt me?

Did I miss any place where I should zero memory after use? Or is there any chance that anything will slip by?
The only thing special about SecureZeroMemory (the Windows version) is that it uses volatile to prevent optimization. Therefore there's no reason to write your own. Just defer to standard algorithms:

std::fill_n((volatile char*)p, n*sizeof(T), 0);


You will probably want to call the global delete:

::operator delete [] p;


Add noexcept:

template &lt;class U&gt; secure_allocator(const secure_allocator&lt;U&gt;&amp;) noexcept {}