Reputation: 1519
for (int i = 0; i < 10; i++)
{
nueron temp; // my Class
_inputNuerons.push_back(temp); // _inputNuerons is a std::vector
}
From what I know , C++ deallocates the temp object when it reaches the } bracket of the for loop. But does storing the object in a std::vector make the object usable later on in the program ? Now when I try to access the "temp" nueron outside the for loop , the program crashes.
How can I store my objects in a std::vector such that it is usable later on ?
Upvotes: 0
Views: 431
Reputation: 5566
How can I store my objects in a std::vector such that it is usable later on ?
The compiler creates a copy constructor for you if you don’t provide your own (and do not delete it).
The body of the compiler-created-copy-constructor is NOT empty, and it will copy all data members of the passed nueron object (temp) to the object which is being created in the element of the vector.
Thus the following works fine:
for (int i = 0; i < 10; i++)
{
Nueron temp; // my Class
_inputNuerons.push_back(temp); // _inputNuerons is a std::vector
}
new Nueron temp is constructed at the left-brace starting the loop and
the object temp is destroyed at the right-brace ending the loop and
the push_back copies temp (via compiler provided copy ctor) into the next element of the vector
Here is some code to illustrate the compiler generated default copy ctor.
Note that this default ctor provides a unique value for each Nueron. This is just for fun and to make it easy to see that all elements are copied and initialized with compiler provided default code.
note 1 - You can size and fill a vector in the same line,
and
note 2 - you can build an element on your stack, and apply push_back().
Example code:
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);
}
reports:
============================================= t207a():
content 1: 1 2 3 4 5 6 7 8 9 10
vector element size: 4 bytes
element vector bytes stack use bytes heap use count capacity 'sizeof(vector)' (element count * element size) 5 5 24 20 10 10 24 40
edit -
With respect to the other answers that might be interpreted as suggesting putting the vector itself into heap ... I have prepared the following code to illustrate why this is not necessary.
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);
}
With output:
=============================================
t207b(): vector element size: 4 byteselement 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
Summary - for g++ version 4.9.2, on Ubuntu 15.04:
column 3 shows that regardless of the number of elements in the vector OR the size of the elements, the stack impact is always only 24 bytes. (i.e. sizeof())
column 1 and 2 show the implementations choice for vector growth (i.e. binary)
column 4 shows total bytes in the vector. Vector guarantees that all the elements are back to back. In this example the code quit with 500 million element entered, and 1 GByte in (I presume) dynamic memory.
This stack impact is so small, you probably do not want to push the vector to the heap.
Upvotes: 1
Reputation: 1364
Your neuron object will be destroyed at the end of for block. You should use dynamic allocation, and store the pointer on that object in vector.
for (int i = 0; i < 10; i++)
{
nueron* temp = new neuron(); // my Class
_inputNuerons.push_back(temp); // _inputNuerons is a std::vector
}
_inputNeurons collection should be collection of neuron pointers.
Upvotes: 1