title: Intermittent "Aborted Core Dumped". Maybe static_cast's fault?
body: <p>I'm writing a graph based backpropagation neural net, as a personal project. Still on the forward prop step. It compiles. Successfully runs half the time, crashes at the very last step half the time. It appears to be dying on some garbage collection step. I'm new to virtual functions and static_cast, so I wonder if those parts are to blame. GDB says "Program received signal SIGABRT, Aborted. 0x00000000100404740 in __gnu_cxx::new_allocator::deallocate(double*, unsigned long) ()"</p>
  
  <p>The functions making up the first half or so of the code are probably not to blame, as they work in a simpler older version of my neural net (without graphs). I bet it's in the structs somewhere. </p>
  
  <p><strong>Update:</strong> If I seed the random number generation with 123 instead of a time based random seed, it runs every time. seed=124 fails every time. Removing the randomness in favor of constant weights also allows it to run every time. I'm baffled!</p>
  
  <pre><code>#include &lt;bits/stdc++.h&gt;
  using namespace std;
  
  #define p(x) cout &lt;&lt; #x &lt;&lt; " = "&lt;&lt; x&lt;&lt; endl
  #define min(a,b) a&lt;b ? a : b
  typedef vector&lt;double&gt; d1;
  typedef vector&lt;d1&gt; d2;
  typedef vector&lt;d2&gt; d3;
  typedef vector&lt;int&gt; i1;
  
  int argmax(d1 x){
    p(x.size());
    int maxIndex=0;
    double maxValue=x[0];
    for (int i=1; i&lt;x.size(); i++){
      if (x[i] &gt; maxValue){
        maxValue = x[i];
        maxIndex = i;
      }
    }
    return maxIndex;
  }
  
  d1 zeros(int n){
    return d1(n);
  }
  
  d2 zeros(int rows, int cols){
    return d2(rows, d1(cols, 0));
  }
  
  d3 zeros(int x, int rows, int cols){
    return d3(x, d2(rows, d1(cols, 0)));
  }
  
  void print(d1 x){
    for (double d: x)
    cout &lt;&lt; d &lt;&lt; endl;
    cout &lt;&lt; endl;
  }
  
  void print(d2 x){
    for (auto row: x){
      for (double d: row){
        cout &lt;&lt; d &lt;&lt; " ";
      }
      cout &lt;&lt; endl;
    }
    cout &lt;&lt; endl;
  }
  
  void print(d3 x){
    for (d2 X: x)
    print(X);
  }
  
  
  
  void toRank2(d1&amp;x, int rows, d2&amp; y){
    for (int i=0; i&lt;x.size()/rows; i++){
      y.emplace_back();
      for (int row=0; row&lt;rows; row++){
        y[i].push_back(x[i*rows+row]);
      }
    }
  }
  
  void toRank3(d1&amp; x, int rows, int cols, d3&amp; y){
    for (int i=0; i&lt;x.size()/rows/cols; i++){
      y.emplace_back();
      for (int row=0; row&lt;rows; row++){
        y[i].emplace_back();
        for (int col=0; col&lt;cols; col++){
          y[i][row].push_back(x[i*rows*cols+row*cols+col]);
        }
      }
    }
  }
  
  d1 getRandomDoubles(int size, double mean=0, double standard_deviation=1){
    static normal_distribution&lt;double&gt; distribution(mean, standard_deviation);
    int seed=time(NULL);
    static default_random_engine generator(seed);
    d1 data(size);
    generate(data.begin(), data.end(), []() { return distribution(generator); });
    return data;
  }
  
  d2 getRandomDoubles(int rows, int cols, double mean=0, double standard_deviation=1){
    d1 d = getRandomDoubles(rows*cols, mean, standard_deviation);
    d2 e;
    toRank2(d, cols, e);
    return e;
  }
  
  d3 getRandomDoubles(int depth, int rows, int cols, double mean=0, double standard_deviation=1){
    d1 d = getRandomDoubles(depth*rows*cols, mean, standard_deviation);;
    d3 e;
    toRank3(d, rows, cols, e);
    return e;
  }
  
  struct Node{
    vector&lt;Node*&gt; parents, children;
    bool ready=false;
    //
    // bool check_ready(){
    //   for (Node* n: parents)
    //   if (!n-&gt;check_ready())
    //   return false;
    //   return true;
    // }
    //
    void add_child(Node&amp; n){
      children.push_back(&amp;n);
      n.parents.push_back(this);
    }
  
    void forward_propagate(){
      cout &lt;&lt; "starting r2 forward" &lt;&lt;endl;
    //  if (parents.size()==0 || updated_parents == parents.size()-1)
      for (Node* n: children){
        cout &lt;&lt; "loop" &lt;&lt; endl;
        n-&gt;update_state();
        //  cout &lt;&lt; "root child forward" &lt;&lt; endl;
      }
      cout &lt;&lt; "exiting r2 forward" &lt;&lt; endl;
      //updated_parents++;
    }
  
    virtual void update_state(){
      //if (parents.size()==0 || updated_parents == parents.size() - 1)
      forward_propagate();
    }
  };
  
  struct r1:Node{
    vector&lt;double&gt; state;
    int r;
  
    r1(){}
  
    r1(int R){
      r=R;
      state = vector&lt;double&gt;(r);
    }
  };
  
  struct r2:Node{
    vector&lt;vector&lt;double&gt;&gt; state;
    int r,c;
  
    r2(){}
    r2(int R, int C){
      r=R;
      c=C;
      state = zeros(r, c);
    }
  };
  
  struct r3:Node{
    d3 state;
    int r, c, d;
    r3(){}
    r3(int R, int C, int D){
      r=R;
      c=C;
      d=D;
      state = zeros(R,C,D);
    }
  };
  
  struct MatrixProduct1_1: r1{
    MatrixProduct1_1(int n):r1(n){}
  
    void update_state() override{
      cout &lt;&lt; "mat11" &lt;&lt; endl;
      d2&amp; W = static_cast&lt;r2*&gt;(parents[0])-&gt;state;
      d1&amp; x = static_cast&lt;r1*&gt;(parents[1])-&gt;state;
      state = zeros(r);
      for (int i=0; i&lt;W.size(); i++)
      for (int j=0; j&lt;W[0].size(); j++)
      state[i] += W[i][j]*x[j];
      forward_propagate();
    }
  };
  
  struct MatrixProduct2_1: r1{
    MatrixProduct2_1(int n):r1(n){}
  
    void update_state() override{
      cout &lt;&lt; "matt21" &lt;&lt; endl;
      d3&amp; W = static_cast&lt;r3*&gt;(parents[0])-&gt;state;
      d2&amp; x = static_cast&lt;r2*&gt;(parents[1])-&gt;state;
      state = zeros(r);
      for (int i=0; i&lt;W.size(); i++)
      for (int j=0; j&lt;W[0].size(); j++)
      for (int k=0; k&lt;W[0][0].size(); k++)
      state[k] += W[i][j][k]*x[i][j];
      forward_propagate();
    }
  };
  
  struct Convolution: r2{
    Convolution(int r, int c): r2(r, c){}
    void update_state() override{
      cout &lt;&lt; "convolving" &lt;&lt; endl;
      state = zeros(r, c);
      d2&amp; W = static_cast&lt;r2*&gt;(parents[0])-&gt;state;
      d2&amp; x = static_cast&lt;r2*&gt;(parents[1])-&gt;state;
  
      int wCenterX = W[0].size() / 2;
      int wCenterY = W.size() / 2;
      int rows = x.size(), cols = x[0].size();
      int wRows = W.size(), wCols = W[0].size();
  
      //#pragma omp parallel for
      for(int i=0; i &lt; rows; i++)
      for(int j=0; j &lt; cols; j++)
      for(int m=0; m &lt; W.size(); m++){
        int mm = W.size() - 1 - m;
        for(int n=0; n &lt; wCols; n++){
          int nn = wCols - 1 - n;
          int ii = i + (m - wCenterY);
          int jj = j + (n - wCenterX);
          if (ii &gt;= 0 &amp;&amp; ii &lt; rows &amp;&amp; jj &gt;= 0 &amp;&amp; jj &lt; cols)
          state[i][j] += x[ii][jj] * W[mm][nn];
        }
      }
      forward_propagate();
    }
  };
  
  
  struct RELU: r2{
    RELU(int r, int c):r2(r, c){}
    void update_state() override{
      cout &lt;&lt; "relu2" &lt;&lt; endl;
      state = zeros(r,c);
      d2&amp; x = static_cast&lt;r2*&gt;(parents[0])-&gt;state;
      for (int i=0; i&lt;state.size(); i++)
      for (int j=0; j&lt;state[0].size(); j++)
      if (x[i][j] &gt; 0)
      state[i][j] = x[i][j];
      forward_propagate();
    }
  };
  
  struct Softmax: r1{
    Softmax(int r):r1(r){}
    void update_state() override{
      cout &lt;&lt; "softmax" &lt;&lt; endl;
      state = zeros(r);
      p(parents.size());
      d1&amp; x = static_cast&lt;r1*&gt;(parents[0])-&gt;state;
      cout &lt;&lt; "got state" &lt;&lt; endl;
      //p(x.size());
      //print(x);
  
      p(x.size());
      cout &lt;&lt; "argmax " &lt;&lt; argmax(x) &lt;&lt; endl;
      double largest = x[argmax(x)];
      double lndenom = largest;
      double expsum = 0;
      cout &lt;&lt; "starting expsum" &lt;&lt; endl;
      for (int i=0; i&lt;x.size(); i++)
      //expsum += exp(x[i]-largest);
      expsum += x[i] - largest;
      cout &lt;&lt; "next loop " &lt;&lt; endl;
      for (int i=0; i&lt;x.size(); i++)
    //  state[i] = exp(x[i]-largest) / expsum;
      state[i] = x[i]-largest;
      cout &lt;&lt; "forward proping" &lt;&lt; endl;
      cout &lt;&lt; "weird" &lt;&lt; endl;
    //  forward_propagate();
      cout &lt;&lt; "done with softmax" &lt;&lt;endl;
    }
  };
  
  struct Add1: r1{
    Add1(int r):r1(r){}
    void update_state() override{
      cout &lt;&lt; "add1ing" &lt;&lt; endl;
      d1&amp; x = static_cast&lt;r1*&gt;(parents[0])-&gt;state;
      d1&amp; y = static_cast&lt;r1*&gt;(parents[1])-&gt;state;
      for (int i=0; i&lt;r; i++)
      state[i] = x[i]+y[i];
      forward_propagate();
    }
  };
  
  struct Add2: r2{
    Add2(int r, int c): r2(r, c){}
    void update_state() override{
      d2&amp; x = static_cast&lt;r2*&gt;(parents[0])-&gt;state;
      d2&amp; y = static_cast&lt;r2*&gt;(parents[1])-&gt;state;
      for (int i=0; i&lt;x.size(); i++)
      for (int j=0; j&lt;x[0].size(); j++)
      state[i][j] = x[i][j] + y[i][j];
      forward_propagate();
    }
  };
  
  struct MaxPool: r2{
    MaxPool(int r, int c): r2(r, c){}
    void update_state() override{
      d2&amp; x = static_cast&lt;r2*&gt;(parents[0])-&gt;state;
      for (int i=0; i&lt;x.size(); i+=2)
      for (int j=0; j&lt;x[0].size(); j+=2)
      state[i/2][j/2] = max(max(x[i][j], x[i+1][j]), max(x[i+1][j], x[i+1][j+1]));
      forward_propagate();
    }
  };
  
  int main(){
    Node root;
    r2 x;
    x.state = getRandomDoubles(28,28);
    r2 wConv;
    wConv.state = getRandomDoubles(10, 10);
    root.add_child(x);
    root.add_child(wConv);
    Convolution c(28,28);
    wConv.add_child(c);
    x.add_child(c);
    Add2 a(28,28);
    r2 bConv(28,28);
    bConv.state = getRandomDoubles(28,28);
    c.add_child(a);
    bConv.add_child(a);
    RELU r(28,28);
    a.add_child(r);
    MaxPool max(14, 14);
    r.add_child(max);
    r3 wFull(10,28,28);
    wFull.state = getRandomDoubles(10,28,28);
    // print(wFull.state);
    // return 0;
    MatrixProduct2_1 full(10);
    wFull.add_child(full);
    max.add_child(full);
    r1 bFull(10);
    bFull.state = getRandomDoubles(10);
    Add1 aFull(10);
    aFull.state[0] = 123;
    full.add_child(aFull);
    bFull.add_child(aFull);
    Softmax s(10);
    aFull.add_child(s);
    // d1&amp; x =         static_cast&lt;r1*&gt;(parents[0])-&gt;state;
    // d1&amp; asdf = static_cast&lt;r1*&gt;(s.parents[0])-&gt;state;
    // print(asdf);
    //root.forward_propagate();
    x.forward_propagate();
    //print(s.state);
    cout &lt;&lt; "returning main";
  }
  </code></pre>