Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

strange behavior when resize container [duplicate]

Tags:

c++

vector

when resizing a vector ,it will call constructor then destruct it.

struct CAT
{
    CAT(){cout<<"CAT()"<<endl;}
    CAT(const CAT& c){cout<<"CAT(const CAT& c)"<<endl;};
    ~CAT(){cout<<"~CAT()"<<endl;};
};
int main()
{
    vector<CAT> vc(6);
    cout<<"-----------------"<<endl;
    vc.resize(3);
    cout<<"-----------------"<<endl;

}

output:

$./m 
CAT()
CAT(const CAT& c)
CAT(const CAT& c)
CAT(const CAT& c)
CAT(const CAT& c)
CAT(const CAT& c)
CAT(const CAT& c)
~CAT()
-----------------
CAT()          //why resize will call constructor?
~CAT()
~CAT()
~CAT()
~CAT()
-----------------
~CAT()
~CAT()
~CAT()

I am using ubuntu 13.10 and gcc4.8

like image 350
camino Avatar asked Jan 23 '14 17:01

camino


3 Answers

That's because of the optional argument for resize.

This is the implementation I have in GCC 4.8:

  void
  resize(size_type __new_size, value_type __x = value_type())
  {
if (__new_size > size())
  insert(end(), __new_size - size(), __x);
else if (__new_size < size())
  _M_erase_at_end(this->_M_impl._M_start + __new_size);
  }

Take a closer look to value_type __x = value_type().

From http://www.cplusplus.com/reference/vector/vector/resize/:

void resize (size_type n, value_type val = value_type());
like image 100
JuanR Avatar answered Nov 19 '22 03:11

JuanR


Before C++11, resize had a defaulted second argument to provide a value for initialising new elements:

void resize(size_type sz, T c = T());

which explains why you see an extra object created and destroyed.

In a modern library, this is replaced with two overloads

void resize(size_type sz);
void resize(size_type sz, const T& c);

so you shouldn't see any extra objects unless you explicitly provide one. You should also see default-initialisation, rather than copy-initialisation, during construction.

like image 41
Mike Seymour Avatar answered Nov 19 '22 02:11

Mike Seymour


It is possible that your implementation of vector::resize creates a temporary default-initialized object even when downsizing, because it uses it to initialize new elements when it's upsizing.

like image 3
Mark Ransom Avatar answered Nov 19 '22 02:11

Mark Ransom