在std :: vector中存储对象是否会增加对象的生命周期?

时间:2015-06-26 20:43:18

标签: c++ memory-management stdvector

for (int i = 0; i < 10; i++)
    { 
        nueron temp; // my Class
        _inputNuerons.push_back(temp); // _inputNuerons is a std::vector 
    }

据我所知,C ++在到达for循环的}括号时释放临时对象。 但是将对象存储在std :: vector中会使该对象稍后在程序中使用吗? 现在,当我尝试访问for循环外的“temp”nueron时,程序崩溃了。

如何将我的对象存储在std :: vector中,以便以后可以使用?

2 个答案:

答案 0 :(得分:1)

您的神经元对象将在阻止结束时被销毁。 您应该使用动态分配,并将指针存储在向量中的该对象上。

for (int i = 0; i < 10; i++)
{ 
    nueron* temp = new neuron(); // my Class
    _inputNuerons.push_back(temp); // _inputNuerons is a std::vector 
}

_inputNeurons集合应该是神经元指针的集合。

答案 1 :(得分:1)

  

如何将我的对象存储在std :: vector中以使其可用   以后呢?

如果您不提供自己的(并且不删除它),编译器会为您创建一个复制构造函数。

compiler-created-copy-constructor的主体不为空,它将传递的nueron对象(temp)的所有数据成员复制到在向量元素中创建的对象。

因此以下工作正常:

for (int i = 0; i < 10; i++)
{ 
    Nueron temp; // my Class
    _inputNuerons.push_back(temp); // _inputNuerons is a std::vector 
}
  • 新的Nueron temp在左支撑处构建,开始循环并且

  • 对象temp在结束循环的右括号中被销毁,

  • push_back将temp(通过编译器提供的copy ctor)复制到向量的下一个元素

这里有一些代码来说明编译器生成的默认复制ctor。

请注意,此默认ctor为每个Nueron提供唯一值。这只是为了好玩,并且很容易看到所有元素都是使用编译器提供的默认代码进行复制和初始化的。

注1 - 您可以在同一行中调整和填充矢量,
和 注2 - 您可以在堆栈上构建一个元素,并应用push_back()。

示例代码:

int seqNum(bool restart=false) // when true restart seqnum
{
   static int SeqNum = 0;
   if(restart) SeqNum = 0; 
   return (SeqNum++);
}

class Nueron
{
public:

   Nueron() : i1(seqNum()) {}  // you provide the default ctor 

   // default dtor - use the compiler provided dtor

   // default copy ctor - use the compiler provided copy ctor

   std::string show()
      {
         std::stringstream ss;
         ss << DTB::digiComma(i1);
         return (ss.str());
      };    

private:
   int i1;
};


void headerShow(std::stringstream& ss)
{
   ss << " vector element size: " << std::setw(5) << sizeof(Nueron) << "  bytes\n" // header
      << "\n"
      << std::setw(15) << "element"
      << std::setw(15) << "vector"
      << std::setw(20) << "bytes stack use"
      << std::setw(24) << "bytes heap use\n"

      << std::setw(15) << "  count"
      << std::setw(15) << "capacity"
      << std::setw(20) << "'sizeof(vector)'"
      << std::setw(24) << "     (element count * element size)\n";
}

void infoShow(std::vector<Nueron>& n, std::stringstream& ss)
{
   ss << std::setw(15) << DTB::digiComma(n.size())    // element count
      << std::setw(15) << DTB::digiComma(n.capacity()) // vector capacity
      << std::setw(18) << DTB::digiComma(sizeof(n))   // bytes stack use
      << std::setw(24) << DTB::digiComma (n.size() * sizeof(Nueron)) // bytes heap use
      << std::endl;
}

void contentShow(size_t               indx,
                 std::vector<Nueron>& n,
                 std::stringstream&   ss,
                 size_t               limit1,
                 size_t               limit2 = 0)
{
   ss << " content " << indx << ": ";

   for (size_t i=0; i<limit1; ++i)
      ss << n[i].show() << "  ";

   if(limit2)
   {
      ss << "...  ";
      for (size_t i=(n.size()-limit2); i<n.size(); ++i)
         ss << std::setw(10) << n[i].show() << "  ";
   }
   ss << std::endl;
}


int t207a(void)
{
   std::cout << "\n============================================= " << "\nt207a():" << std::endl;
   (void)seqNum(true); // restart seq from 0

   std::stringstream ss1;
   std::stringstream ss2;

   std::vector<Nueron> neuron(5);  // default ctor used 5 times
   headerShow(ss1);
   infoShow(neuron, ss1);

   // add 5 more using 'free' copy ctor
   for (size_t i=0; i<5; ++i)
   {
      Nueron temp;             // use ctor
      neuron.push_back(temp);  // use compiler provided copy ctor
   }
   infoShow(neuron, ss1);

   ss2 << "\n";
   contentShow(1, neuron, ss2, 10, 0);

   std::cout << ss2.str() << std::endl << ss1.str() << std::endl;

   // neuron dtor runs here
   return(0);
}

报告:

  

============================================= t207a( ):

     

内容1:1 2 3 4 5 6 7 8 9 10

     

向量元素大小:4个字节

    element         vector     bytes stack use         bytes heap use
      count       capacity    'sizeof(vector)'     (element count * element size)
          5              5                24                      20
         10             10                24                      40

编辑 -

关于可能被解释为建议将向量本身放入堆中的其他答案......我准备了以下代码来说明为什么这不是必需的。

int t207b(void)
{
   std::cout << "\n============================================= " << "\nt207b():" << std::endl;
   (void)seqNum(true); // restart seq from 0

   std::stringstream ss1;
   std::stringstream ss2;

   std::vector<Nueron> neuron; // no elements
   headerShow(ss1);
   infoShow(neuron, ss1);

   size_t cap1 = neuron.capacity();

   // add elements using 'free' copy ctor
   do
   {
      {
         Nueron temp;             // use ctor
         neuron.push_back(temp);  // use compiler provided copy ctor
      }
      size_t cap2 = neuron.capacity();

      if(cap2 != cap1)
      {
         cap1 = cap2;

         infoShow(neuron, ss1);

         if (cap2 > 500000000) break;
         //          12345678
      }

   }while(1);
   contentShow(1, neuron, ss2, 10, 0);

   std::cout << ss1.str() << "\n" << std::endl << ss2.str() << std::endl;
   // neuron dtor runs here
   return(0);
}

输出:

  

============================================= <无线电通信/>   t207b():向量元素大小:4个字节

    element         vector     bytes stack use         bytes heap use
      count       capacity    'sizeof(vector)'     (element count * element size)
          0              0                24                       0
          1              1                24                       4
          2              2                24                       8
          3              4                24                      12
          5              8                24                      20
          9             16                24                      36
         17             32                24                      68
         33             64                24                     132
         65            128                24                     260
        129            256                24                     516
        257            512                24                   1,028
        513          1,024                24                   2,052
      1,025          2,048                24                   4,100
      2,049          4,096                24                   8,196
      4,097          8,192                24                  16,388
      8,193         16,384                24                  32,772
     16,385         32,768                24                  65,540
     32,769         65,536                24                 131,076
     65,537        131,072                24                 262,148
    131,073        262,144                24                 524,292
    262,145        524,288                24               1,048,580
    524,289      1,048,576                24               2,097,156
  1,048,577      2,097,152                24               4,194,308
  2,097,153      4,194,304                24               8,388,612
  4,194,305      8,388,608                24              16,777,220
  8,388,609     16,777,216                24              33,554,436
 16,777,217     33,554,432                24              67,108,868
 33,554,433     67,108,864                24             134,217,732
 67,108,865    134,217,728                24             268,435,460
134,217,729    268,435,456                24             536,870,916
268,435,457    536,870,912                24           1,073,741,828

摘要 - 对于g ++版本4.9.2,在Ubuntu 15.04上:

  • 第3列显示,无论向量中的元素数量或元素的大小如何,堆栈影响始终只有24个字节。 (即sizeof())

  • 第1列和第2列显示了向量增长的实现选择(即二进制)

  • 第4列显示了向量中的总字节数。 Vector保证所有元素都背靠背。在这个例子中,代码退出时输入了500万个元素,并且(我假设)动态内存为1 GBy。

此堆栈影响非常小,您可能不希望将向量推送到堆中。