-5

I was so sure that vector calls the destructors of the contained objects that I just used the clear() on the main vector and then I reused the vector and the values of the vectors stored in it were not cleared...

EDIT - code:

vector<vector<int> > flush1;
flush1.reserve(4);
for(int i = 0; i != 4; ++i) flush1[i].reserve(7);
flush1.clear();
flush1[0].push_back(some_int);
flush1[1].push_back(some_int);
flush1[2].push_back(some_int);
flush1[3].push_back(some_int);
cout the size from flush1[0-3];
flush1.clear();

and again

flush1[0].push_back(some_int);
flush1[1].push_back(some_int);
flush1[2].push_back(some_int);
flush1[3].push_back(some_int);

and cout-ing the size from flush1[0-3] cout-s their previous size + new sizes (addition of old and new)

braX
  • 11,506
  • 5
  • 20
  • 33
Lukas Salich
  • 959
  • 2
  • 12
  • 30
  • OK, but I need time to select those parts from my code. – Lukas Salich Sep 21 '12 at 11:33
  • 1
    Your code is wrong, and/or so is your understanding of the container. There is no legal way in which you could possibly conclude that the "elements are still there". – Kerrek SB Sep 21 '12 at 11:39
  • The vectors stored in it *aren't* cleared, they're destroyed. After you call `clear()` the main vector has no elements, that's the whole point of clear. So you can't determine whether the "vectors stored in it" were or weren't cleared. There are no vectors stored in it. – Steve Jessop Sep 21 '12 at 11:43
  • The question is, how did you "reuse" the vector? – Xeo Sep 21 '12 at 11:47
  • I edited the question, I don't say it's bad C++ behavior, I just don't know why it doesn't clear the stored vectors. – Lukas Salich Sep 21 '12 at 11:59
  • The test is easy: populate a vector with object that print in their destructor and then clear the vector. Then redo the test with a vector of vectors populated with these objects. – stefaanv Sep 21 '12 at 12:00
  • To use a vector with operator[], you must initialize the vector correctly or use resize(), not reserve() – stefaanv Sep 21 '12 at 12:03
  • @stefaanv That sounds true, I try to resize the main vector, but I don't know the size of contained vectors, so I reserve the size of them only on the maximum possible size. – Lukas Salich Sep 21 '12 at 12:07
  • @stefaanv So the resize on the main vector instead reserving is not usable for my program. – Lukas Salich Sep 21 '12 at 12:17
  • @LukasSalich: reserve/push_back is good, resize/operator[] is good, reserve/operator[] is wrong: no entries are created, just room to push_back entries into. – stefaanv Sep 21 '12 at 12:54
  • If you want the vector to check that your accesses are valid, then use `flush1.at(i)` rather than `flush1[i]`. That will check the index and throw an exception if it's out of range. By using `[]`, you are saying that you already know that the index is valid and, if it isn't (such as in every one of your accesses), you get undefined behaviour. – Mike Seymour Sep 21 '12 at 12:58
  • @MikeSeymour But on the toher hand, it goes through 10 billion iterations, so I don't want to use slow .at(i). – Lukas Salich Sep 21 '12 at 14:32
  • @stefaanv Thanks, I figured it out now by myself. So I need a vector[4] and do it this way: vector.reserve(4); vector.resize(4);, is it best? So I don't reserve more than needed and I resize on the size that I can use all 4 elements. – Lukas Salich Sep 21 '12 at 14:34
  • @LukasSalich: `vector.reserve(4)` is pointless before `vector.resize(4)`, just use resize. – stefaanv Sep 21 '12 at 14:45
  • @LukasSalich: Indeed; if `at()` is too slow then use `[]`. But in that case, don't be shocked that there isn't a compile-time check, and a dodgy index gives undefined behaviour - you've asked for unchecked access. – Mike Seymour Sep 21 '12 at 15:49
  • @stefaanv Why is it pointless? I think that if I don't reserve(4), then the resize resizes on size 4 and allocates some more memory which won't be used anyway. Is it true? – Lukas Salich Sep 22 '12 at 16:37
  • I'm bouncing that question back: what made you think that reserve and resize use different allocations? – stefaanv Sep 22 '12 at 21:20
  • I thought that reserve sets the allocated amount for each allocating step and resize uses those amounts to allocate needed memory plus some more depending on the amount to be allocated. For example I reserve 50 and resize on 60, so 40 more (100-60) will be allocated for nothing. I also think that vector allocates 2 times more in every allocating step. – Lukas Salich Sep 22 '12 at 23:42

1 Answers1

3

The vector object has three pointers: the beginning, the end and end-of-reserved-storage.

The clear() method calls the destructor on each contained object and then sets the end pointer to the beginning.

So the data of the destructed objects will still be visible (using a debugger for example) in the reserved storage.

StackedCrooked
  • 34,653
  • 44
  • 154
  • 278
  • So you don't think it's bad to still contain information after clearing the main vector of those vectors stored inside even that they don't exist in my code anymore? – Lukas Salich Sep 21 '12 at 12:04
  • The information is still there but it can be considered "garbage". There is a lot of garbage at anytime in your computer's RAM and on your hard disk. It's normal. – StackedCrooked Sep 21 '12 at 12:33