C ++向量不存储类

时间:2018-06-30 01:12:08

标签: c++ c++11 vector

我正在用c ++写一个简单的前馈神经网络,但是当我尝试将我的神经元类存储在我的层结构中时,它崩溃并给出以下输出:

terminate called after throwing an instance of '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.

这是我的程序:

#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;
}

我不认为这很难理解,但是如果我试图用层结构中的神经元类创建一个向量,但是即使我只将一个神经元放入向量中,它也表示没有足够的内存分配给该程序。我曾尝试将神经元类转换为结构,但这没有帮助。

2 个答案:

答案 0 :(得分:1)

在初始化weights之前,正在使用insN内联初始化您的insN成员。目前最简单的解决方法是将成员声明更改为:

float* weights;

和构造函数:

neuron(int _insN, int _funtype) : insN(_insN), funtype(_funtype), weights(new float[insN]) {

}

请注意,初始化列表中的成员已初始化in the order they are declared(请参阅“初始化顺序”)。

一个更好的长期解决方案是使weights成为std::vector<float>,以及代码中的每个其他动态float*数组,目前这些数组有很多内存泄漏。 / p>

答案 1 :(得分:0)

weights成员在insN初始化之前被初始化。访问insN的值将导致未定义的行为,并且运算符new分配了不确定的内存量。这就是报告bad_array_new_length的异常的原因(实际上,分配的数字可能超出了计算机上的可用内存,尽管这只是编译器的偶然情况)。

这是在构造函数中初始化insN之前发生的。

对此的部分解决方法是从类主体中删除初始化程序,并将构造函数更改为

neuron(int _insN, int _funtype) : insN(_insN), funtype(_funtype), weights(new float[_insN])
{}

即使已解决,您的代码也有许多其他问题。我会在这里列出部分清单。

std::vector假定其元素具有工作副本构造函数和赋值运算符。您的班级没有,所以没有遵守规则。这意味着元素的复制(例如,只要调整向量的大小就可能发生)将创建将无法正确运行的对象(例如,在一个对象中更改weights的元素将无意中更改另一个对象中的元素) 。查找(例如使用Google)“三个规则”或“五个规则”以解决该问题。更好的是,将weights设为std::vector<float>而不是指针,然后遵循“零规则”。

您的类没有定义析构函数,因此永远不会释放使用操作符weights为每个对象分配给new的内存。因此,每当创建neuron的实例时,就会发生内存泄漏。再次,查找“三个规则”,“五个规则”或“零个规则”以解决该问题。

上面的某些注释也适用于您的layer类。