Fix horrific performance found by gmaxwell.
authorMatt Corallo <matt@bluematt.me>
Tue, 3 Jan 2012 08:03:07 +0000 (00:03 -0800)
committerMatt Corallo <matt@bluematt.me>
Thu, 5 Jan 2012 00:46:16 +0000 (19:46 -0500)
src/serialize.h

index 5455590..626f7d6 100644 (file)
@@ -819,6 +819,38 @@ struct secure_allocator : public std::allocator<T>
 };
 
 
+//
+// Allocator that clears its contents before deletion.
+//
+template<typename T>
+struct zero_after_free_allocator : public std::allocator<T>
+{
+    // MSVC8 default copy constructor is broken
+    typedef std::allocator<T> base;
+    typedef typename base::size_type size_type;
+    typedef typename base::difference_type  difference_type;
+    typedef typename base::pointer pointer;
+    typedef typename base::const_pointer const_pointer;
+    typedef typename base::reference reference;
+    typedef typename base::const_reference const_reference;
+    typedef typename base::value_type value_type;
+    zero_after_free_allocator() throw() {}
+    zero_after_free_allocator(const zero_after_free_allocator& a) throw() : base(a) {}
+    template <typename U>
+    zero_after_free_allocator(const zero_after_free_allocator<U>& a) throw() : base(a) {}
+    ~zero_after_free_allocator() throw() {}
+    template<typename _Other> struct rebind
+    { typedef zero_after_free_allocator<_Other> other; };
+
+    void deallocate(T* p, std::size_t n)
+    {
+        if (p != NULL)
+            memset(p, 0, sizeof(T) * n);
+        std::allocator<T>::deallocate(p, n);
+    }
+};
+
+
 
 //
 // Double ended buffer combining vector and stream-like interfaces.
@@ -828,7 +860,7 @@ struct secure_allocator : public std::allocator<T>
 class CDataStream
 {
 protected:
-    typedef std::vector<char, secure_allocator<char> > vector_type;
+    typedef std::vector<char, zero_after_free_allocator<char> > vector_type;
     vector_type vch;
     unsigned int nReadPos;
     short state;