diff options
author | Andreas Kling <awesomekling@gmail.com> | 2019-03-17 15:53:03 +0100 |
---|---|---|
committer | Andreas Kling <awesomekling@gmail.com> | 2019-03-17 15:53:03 +0100 |
commit | ef05d8cbf6ac5e378d3d9205ef095de754f6a8d2 (patch) | |
tree | a18ed5aed3eb7a0602e8694c9eb0f625c1a41389 | |
parent | 4e451c1e92b36e57f3dd5cfe55517074da7e8e20 (diff) | |
download | serenity-ef05d8cbf6ac5e378d3d9205ef095de754f6a8d2.zip |
AK: Use an OwnPtr for the VectorImpl.
I don't know why it wasn't implemented this way already. This fixes a leak
in operator=(Vector&&) that we were hitting on Ext2FS write.
-rw-r--r-- | AK/Vector.h | 33 |
1 files changed, 15 insertions, 18 deletions
diff --git a/AK/Vector.h b/AK/Vector.h index 45131c06fb..896ffa16f4 100644 --- a/AK/Vector.h +++ b/AK/Vector.h @@ -11,13 +11,17 @@ template<typename T> class Vector; template<typename T> class VectorImpl { public: - ~VectorImpl() { } - static VectorImpl* create(int capacity) + ~VectorImpl() + { + for (int i = 0; i < m_size; ++i) + at(i).~T(); + } + static OwnPtr<VectorImpl> create(int capacity) { int size = sizeof(VectorImpl) + sizeof(T) * capacity; void* slot = kmalloc(size); new (slot) VectorImpl(capacity); - return (VectorImpl*)slot; + return OwnPtr<VectorImpl>((VectorImpl*)slot); } int size() const { return m_size; } @@ -60,9 +64,8 @@ public: ~Vector() { clear(); } Vector(Vector&& other) - : m_impl(other.m_impl) + : m_impl(move(other.m_impl)) { - other.m_impl = nullptr; } Vector(const Vector& other) @@ -74,19 +77,13 @@ public: Vector& operator=(Vector&& other) { - if (this != &other) { - m_impl = other.m_impl; - other.m_impl = nullptr; - } + if (this != &other) + m_impl = move(other.m_impl); return *this; } void clear() { - for (int i = 0; i < size(); ++i) { - at(i).~T(); - } - kfree(m_impl); m_impl = nullptr; } @@ -177,8 +174,7 @@ public: void append(Vector<T>&& other) { if (!m_impl) { - m_impl = other.m_impl; - other.m_impl = nullptr; + m_impl = move(other.m_impl); return; } Vector<T> tmp = move(other); @@ -217,6 +213,8 @@ public: void append(const T* values, int count) { + if (!count) + return; ensure_capacity(size() + count); for (int i = 0; i < count; ++i) new (m_impl->slot(m_impl->m_size + i)) T(values[i]); @@ -235,9 +233,8 @@ public: new (new_impl->slot(i)) T(move(m_impl->at(i))); m_impl->at(i).~T(); } - kfree(m_impl); } - m_impl = new_impl; + m_impl = move(new_impl); } void resize(int new_size) @@ -305,7 +302,7 @@ private: return max(int(4), capacity + (capacity / 4) + 4); } - VectorImpl<T>* m_impl { nullptr }; + OwnPtr<VectorImpl<T>> m_impl; }; } |