summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Kling <awesomekling@gmail.com>2019-03-17 15:53:03 +0100
committerAndreas Kling <awesomekling@gmail.com>2019-03-17 15:53:03 +0100
commitef05d8cbf6ac5e378d3d9205ef095de754f6a8d2 (patch)
treea18ed5aed3eb7a0602e8694c9eb0f625c1a41389
parent4e451c1e92b36e57f3dd5cfe55517074da7e8e20 (diff)
downloadserenity-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.h33
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;
};
}