C++ vector not storing class
C++ vector not storing class
I am writing a simple feed-forward neural network in c++, however when I try to store my neuron class in my layer structure, it crashes and gives this output:
terminate called after throwing an instance of 'std::bad_array_new_length'
terminate called after throwing an instance of 'std::bad_array_new_length'
what(): std::bad_array_new_length
what(): std::bad_array_new_length
This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.
This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.
Here is my program:
#include <iostream>
#include <random>
#include <vector>
using namespace std;
random_device e;
int randomG(int min, int max){
return (e()%(max-min))+min;
}
int f(int v){
return v+5;
}
class neuron{
public:
neuron(int _insN, int _funtype){
insN=_insN;funtype=_funtype;
}
float out;
void genWeights(){
for (int i = 0; i < insN; i++){
weights[i]=float(randomG(1,1000))/100;
}
}
float parceOut(float* ins){
float preOut=0;
for (int i = 0; i < insN; ++i){
preOut+=(weights[i]*ins[i]);
}
out=activation(preOut, funtype);
}
private:
float ReLU(float f){
if (f<=0){return f*0.01;}
else {return f;}
}
float Softmax(float f){
return f;
}
float activation(float f, int function){
switch(function){
case(1): return ReLU(f); break;
case(2): return f; break;
case(3): return Softmax(f); break;
}
}
int insN;
int funtype;
float* weights = new float[insN];
};
struct layer{
int insN=1, neuronN=1;
float* outs=new float[neuronN];
vector<neuron> nS;
void generateNeurons(){
for(int i=0;i<1;i++){
nS.push_back(neuron(insN,1));
}
}
};
int main(int argc, char *argv)
{
layer input;
input.insN=1;
input.neuronN=5;
input.generateNeurons();
cin.get();
return 0;
}
I don't think that it is to hard to understand, but if it is I am trying to make a vector with my neuron class in my layer structure, but even when I put just one neuron in the vector it says that there is not enough memory allocated to the program. I have tried converting the neuron class into a structure, but that did not help.
weights
insN
float* weights = new float[insN];
-- Why are you doing this when you could use std::vector<float> weights(insN);
? There is no need for raw pointers in your code -- all dynamic arrays could be done using vector
. In addition, your code has memory leaks.– PaulMcKenzie
Jun 30 at 1:21
float* weights = new float[insN];
std::vector<float> weights(insN);
vector
You don't know what insN is when it's constructed. Add weights = new float[insN]; to the constructor instead of the class body. It's probably being initialized to an array of length 0.
– ffhighwind
Jun 30 at 1:24
@ffhighwind - an array of length zero is permitted (albeit, any usage of its elements, since it has none, gives undefined behaviour).
– Peter
Jun 30 at 1:59
2 Answers
2
Your weights
member is being inline-initialized using insN
, before insN
is initialized. The simplest fix for now would be to change the member declaration to:
weights
insN
insN
float* weights;
and the constructor to:
neuron(int _insN, int _funtype) : insN(_insN), funtype(_funtype), weights(new float[insN]) {
}
Note that members in the initialization list are initialized in the order they are declared (see 'Initialization order').
A better long-term solution would be make weights
be std::vector<float>
, as well as every other dynamic float*
array in your code, which currently has a number of memory leaks.
weights
std::vector<float>
float*
The weights
member is being initialised before insN
is initialised. Accessing the value of insN
to do that gives undefined behaviour and an indeterminate amount of memory is being allocated with operator new
. That is the reason for the exception which reports a bad_array_new_length
(in practice, the number being allocated probably exceeds available memory on your machine although that's just happenstance with your compiler).
weights
insN
insN
new
bad_array_new_length
That happens before insN
is being initialised in the constructor.
insN
One partial fix for that will be to remove the initialiser from the class body AND change the constructor to
neuron(int _insN, int _funtype) : insN(_insN), funtype(_funtype), weights(new float[_insN])
{}
Even if that is fixed, your code has numerous other problems too. I'll give a partial list here.
std::vector
assumes its elements have a working copy constructor and assignment operator. Your class does not, so is not playing by the rules. That means copying of elements (as, for example, can happen whenever a vector is resized) will create objects that will not behave correctly (e.g. changing an element of weights
in one object will uninintentionally change an element in another object). Look up (e.g. using google) the "rule of three" or "rule of five" to address that. Better yet, make weights
a std::vector<float>
rather than a pointer, and follow the "rule of zero".
std::vector
weights
weights
std::vector<float>
Your class doesn't define a destructor, so the memory allocated to weights
using operator new
- for each object - is never released. Hence you have a memory leak - whenever an instance of your neuron
is created. Again, look up "rule of three", "rule of five", or "rule of zero" for an approach to address that.
weights
new
neuron
Some of the comments above are applicable to your layer
class as well.
layer
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
Probably initializer for
weights
is being called beforeinsN
is assigned in the body of the constructor.– Daniel Schepler
Jun 30 at 1:18