summaryrefslogtreecommitdiffstats
path: root/base
diff options
context:
space:
mode:
authorgavinp@chromium.org <gavinp@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-11-27 20:44:49 +0000
committergavinp@chromium.org <gavinp@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-11-27 20:44:49 +0000
commite5fd2c23c454bcbc374fb7818be84a934e8f2c59 (patch)
treef6ab523900a08d7eccb7f366e6942117805e46e1 /base
parentf84a9de7b8fcf708f7aba82d136b33ec8229a45f (diff)
downloadchromium_src-e5fd2c23c454bcbc374fb7818be84a934e8f2c59.zip
chromium_src-e5fd2c23c454bcbc374fb7818be84a934e8f2c59.tar.gz
chromium_src-e5fd2c23c454bcbc374fb7818be84a934e8f2c59.tar.bz2
Fix leak in ScopedVector<>::resize()
When resizing a vector to be smaller, delete the disappearing elements. This previously was a leak. Interestingly, the one place this potential leak was tickled, history_backend.cc guarded itself against the leak, and we remove that now redundant guard here too. R=willchan@chromium.org BUG=None Review URL: https://chromiumcodereview.appspot.com/11418140 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@169736 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'base')
-rw-r--r--base/memory/scoped_vector.h8
-rw-r--r--base/memory/scoped_vector_unittest.cc34
2 files changed, 41 insertions, 1 deletions
diff --git a/base/memory/scoped_vector.h b/base/memory/scoped_vector.h
index feb0321..90a1f7d 100644
--- a/base/memory/scoped_vector.h
+++ b/base/memory/scoped_vector.h
@@ -74,7 +74,13 @@ class ScopedVector {
}
void reserve(size_t capacity) { v_.reserve(capacity); }
- void resize(size_t new_size) { v_.resize(new_size); }
+
+ // Resize, deleting elements in the disappearing range if we are shrinking.
+ void resize(size_t new_size) {
+ if (v_.size() > new_size)
+ STLDeleteContainerPointers(v_.begin() + new_size, v_.end());
+ v_.resize(new_size);
+ }
template<typename InputIterator>
void assign(InputIterator begin, InputIterator end) {
diff --git a/base/memory/scoped_vector_unittest.cc b/base/memory/scoped_vector_unittest.cc
index 03774c5..17405e2 100644
--- a/base/memory/scoped_vector_unittest.cc
+++ b/base/memory/scoped_vector_unittest.cc
@@ -130,6 +130,40 @@ TEST(ScopedVectorTest, WeakClear) {
EXPECT_EQ(static_cast<size_t>(0), scoped_vector.size());
}
+TEST(ScopedVectorTest, ResizeShrink) {
+ LifeCycleWatcher first_watcher;
+ EXPECT_EQ(LC_INITIAL, first_watcher.life_cycle_state());
+ LifeCycleWatcher second_watcher;
+ EXPECT_EQ(LC_INITIAL, second_watcher.life_cycle_state());
+ ScopedVector<LifeCycleObject> scoped_vector;
+
+ scoped_vector.push_back(first_watcher.NewLifeCycleObject());
+ EXPECT_EQ(LC_CONSTRUCTED, first_watcher.life_cycle_state());
+ EXPECT_EQ(LC_INITIAL, second_watcher.life_cycle_state());
+
+ scoped_vector.push_back(second_watcher.NewLifeCycleObject());
+ EXPECT_EQ(LC_CONSTRUCTED, first_watcher.life_cycle_state());
+ EXPECT_EQ(LC_CONSTRUCTED, second_watcher.life_cycle_state());
+
+ // Test that shrinking a vector deletes elements in the dissapearing range.
+ scoped_vector.resize(1);
+ EXPECT_EQ(LC_CONSTRUCTED, first_watcher.life_cycle_state());
+ EXPECT_EQ(LC_DESTROYED, second_watcher.life_cycle_state());
+ EXPECT_EQ(1u, scoped_vector.size());
+}
+
+TEST(ScopedVectorTest, ResizeGrow) {
+ LifeCycleWatcher watcher;
+ EXPECT_EQ(LC_INITIAL, watcher.life_cycle_state());
+ ScopedVector<LifeCycleObject> scoped_vector;
+ scoped_vector.push_back(watcher.NewLifeCycleObject());
+ EXPECT_EQ(LC_CONSTRUCTED, watcher.life_cycle_state());
+
+ scoped_vector.resize(5);
+ EXPECT_EQ(LC_CONSTRUCTED, watcher.life_cycle_state());
+ EXPECT_EQ(5u, scoped_vector.size());
+}
+
TEST(ScopedVectorTest, Scope) {
LifeCycleWatcher watcher;
EXPECT_EQ(LC_INITIAL, watcher.life_cycle_state());