Hi Rob
The original question was: how do I ensure the bytes in a std::basic_string
get wiped?
The problems with giving a full answer to that are:
1) libstdc++ used a refcounted basic_string because C++98 didn't outright ban
it, so you can't be sure that the last reference was dropped
2) the standard does permit the "small string optimisation" (SSO) solution,
which allows basic_string to skip the allocator
3) memset can be optimised out of existence -- see Greg K-H's post
https://plus.google.com/111049168280159033135/posts/dr2pf4ku3Cd and follow-up
on how BSD solves it:
https://plus.google.com/111049168280159033135/posts/YTDoSRTrktc
Let's ignore case #1 for the moment, since C++11 ruled that refcounting was
not permitted.
If you want to scrub, there are three options:
- before basic_string's destructor
- during its destructor
- after its destructor
Obviously, the standard cannot recommend doing it before the destructor.
Unlike QByteArray, basic_string does not return a non-const pointer to its
data.
Doing it during the destructor is the expected case of using the allocator,
but it won't work if SSO is in operation. And even if that were the case, the
compiler can prove the memory isn't getting used again, so problem #3 applies.
So the only case available is to do it *after* the destructor has run. That
requires you legitimately have access to the memory area where the
basic_string was placed. The only way I see that happening is if you have an
indirection to the basic_string in the first place.
Such as:
struct Wrapper
{
std::basic_string<char, std::char_traits<char>, MyAllocator> data;
void *operator new(std::size_t);
operator delete(void *);
};
And always allocating that in the heap, so the operator delete member gets to
run.
At that point, it's easier to ditch std::basic_string and just new char[N]
yourself, thus avoiding a double indirection to the data in the non-small
case.
--
Thiago Macieira - thiago (AT)
macieira.info - thiago (AT)
kde.org
Software Architect - Intel Open Source Technology Center
PGP/GPG: 0x6EF45358; fingerprint:
E067 918B B660 DBD1 105C 966C 33F5 F005 6EF4 5358