3

I'm trying to understand std::vector, and I know that if vector is a vector containing user-defined classes it's important that it calls its destructors in case that class has "ownership" of a resource. In this case I imagine that it would loop through each element and call the destructor on each.

But in the case of plain old data, I don't think destructors would need to be called, only a simple delete of the entire block. If I had to guess I'd say this would be faster for say, reallocations.

Would it be fairly easy to implement your own array class which distinguishes these two and behaves different according to what needs to be done? Thanks.

Zebrafish
  • 11,682
  • 3
  • 43
  • 119
  • 3
    What do you mean by "clear"? When or why would a vector need to "clear" its data? Can you perhaps show some code which illustrates your question and the problems you have? And most importantly, is this just curiosity or is there an actual problem you want to solve? What is the *actual* problem then? – Some programmer dude Nov 29 '16 at 08:53
  • It's not that easy to distinguish without `std::is_pod`. Standard library implementers aren't required to preform this check. But I'd be surprised if the popular ones don't do it. – StoryTeller - Unslander Monica Nov 29 '16 at 08:55
  • 1
    If I got your issue correctly you're asking "Can I just std::vector memset everything when clearing or initializing with PODs?". That isn't very C++-way of doing things since if you later add a member that turns your type into a non-pod, you might render things broken. – Marco A. Nov 29 '16 at 08:57
  • @Some programmer dude What I mean by "clearing" is calling the clear() function, or say it goes out of scope and needs to release the memory block. Sorry, no, there's no actual "problem", I just wanted to understand if for example vector might have two different template versions depending on if it contains PODs or objects with destructors etc. , I' – Zebrafish Nov 29 '16 at 08:59
  • 1
    @Marco A. I'm asking that if a POD doesn't need to have destructors called, then looping through each element and deleting it isn't necessary, only the entire block needs to be cleared. I'm not saying to call memset myself, and just wondering if std::vector distinguishes between the two. – Zebrafish Nov 29 '16 at 09:05

1 Answers1

1

From gcc vector implementation:

void
clear()
{ _M_erase_at_end(this->_M_impl._M_start); }

So, clear calls protected function _M_erase_at_end, lets, look at it:

void
_M_erase_at_end(pointer __pos)
{
    std::_Destroy(__pos, this->_M_impl._M_finish, _M_get_Tp_allocator());
    this->_M_impl._M_finish = __pos;
}

And it calls std::_Destroy from beginning of vector (__pos is beginning) till the end.

template<typename _ForwardIterator, typename _Allocator>
void
_Destroy(_ForwardIterator __first, _ForwardIterator __last,
     _Allocator& __alloc)
{
typedef __gnu_cxx::__alloc_traits<_Allocator> __traits;
for (; __first != __last; ++__first)
__traits::destroy(__alloc, std::__addressof(*__first));
}

So, it's iterated all over internal array and call __traits::destroy, not freeing all memory block at once.

EDIT: you wrote But it would seem when clearing vector that it does call delete on its elements - the answer is big NO. STL containers do not OWN externally allocated memory, you always must call delete or use shared\unique_ptr or it will be leak.

Starl1ght
  • 4,422
  • 1
  • 21
  • 49
  • I know that vectors of pointers don't release the memory pointed to by the pointer. Doesn't vector then distinguish between pointer to type and type? It seems to call delete on each element of vector but not vector, that would be a leak, I think. – Zebrafish Nov 29 '16 at 09:26