[Passwordsafe-devel] SecString class
Popular easy-to-use and secure password manager
Brought to you by:
ronys
From: James C. <Ja...@No...> - 2002-05-25 15:37:32
|
I've just join in, and figure that I'd throw in my two cent on the recent conversations: >> I noticed the SecString class at that time was subclassing std::string, which is a big no-no since std::string has no virtual destructor. In some instances, this can lead to the SecString destructor never being called, and hence the memory buffer with the SecString contents never getting cleared. << Actually, there is NO problem here, because there is no conceivable situation where the dtor would not be called. To prove this, you just have to look at the one (inconceivable) scenario, where it is a problem: void Func() { std::string* pStr = GetANewString(); // use pStr delete pStr; // ~std::string() called, not subclass dtor } Further, we must have the ability (and desire) to change GetANewString() (to return a subclass of std::string), but (and here's the key), we must be UNABLE to change Func(). However, considering that code, could there be any possible reason for writing that idiom, *unless* it was to use pStr polymorphically? In which case, the programmer, *expects* a subclass of string there, and so the code is broken before you touched a thing. In other words, we'd be making design decisions based on the theoretically possibility of breaking code that's already broken. Now, if we are able to change Func() (and, since we have the complete source code at our disposal, we would be able to, if such a function existed), then fixing it is trivial: class vstring : public std::string { vstring(const char* _Ptr, size_type _Count = npos) : std::string(_Ptr, _Count) {} // similarly duplicator other ctors virtual ~vstring() = 0; }; class SecString : public vstring { // etc }; void Func() { vstring* pStr = GetANewString(); // use pStr delete pStr; // subclass dtor called } -------------- The problem with the alternative you suggest of create a new instantiation of basic_string with a specific allocator, to that you lose the IS-A relationship of inheritance. For example, an existing function which took a std::string& parameter would work perfectly with a string-derived class, but not with a new basic_string type, since it would have not relationship with std::string. Truth, James Curran |