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.





Probably initializer for weights is being called before insN is assigned in the body of the constructor.
– Daniel Schepler
Jun 30 at 1:18


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.

Comments

Popular posts from this blog

paramiko-expect timeout is happening after executing the command

Opening a url is failing in Swift

Export result set on Dbeaver to CSV