Arduino restarts when a function is called
Your code is very complex and running it in an environment where you have limited debug facilities is making life worse for yourself.

When an Arduino reboots it is usually because it has thrown a memory error.  This happens when you try and access memory that is no longer your program's to access (or never was yours).  In this case I originally suspected, based on the complexity of your code, that you were accessing a vector element that you could no longer access.

To prove this I 'ran it on a desktop', in my case a Windows 7 box with Visual Studio 2015 (but you could have used Linux, GCC and GDB).  This meant I wrote a little wrapper program and stubbed the functions you called.  This resulted in the error message shown below.

This is my 'desktop' code:

#include &lt;vector&gt;

std::vector&lt;std::vector&lt;std::vector&lt;float&gt;&gt;&gt; test_split(const int&amp; i, const float&amp; f, std::vector&lt; std::vector&lt; float &gt; &gt;&amp; dataset)
{
    std::vector&lt;std::vector&lt;std::vector&lt;float&gt;&gt;&gt; vals;
    return vals;
}

float gini_index(const std::vector&lt;int&gt;&amp; class_values, const std::vector&lt;std::vector&lt;std::vector&lt;float&gt;&gt;&gt;&amp; group)
{
    return 1.0f;
}

std::vector&lt;std::vector&lt;std::vector&lt;std::vector&lt;float&gt;&gt;&gt;&gt; get_split(std::vector&lt; std::vector&lt; float &gt; &gt;&amp; dataset) {
    std::vector&lt;int&gt; class_values; // declares vector 'class_values'
    for (int i = 0; i &lt; dataset.size(); i++) { // loops through each value in dataset (the dataset contains vectors)  and appends the last value in each vector to class_values
        class_values.push_back(dataset[i][dataset.size()]);
    }
    std::vector&lt;std::vector&lt;std::vector&lt;float&gt;&gt;&gt; b_index;
    b_index.push_back(std::vector&lt;std::vector&lt;float&gt;&gt;(999));
    std::vector&lt;std::vector&lt;std::vector&lt;float&gt;&gt;&gt; b_value;
    b_value.push_back(std::vector&lt;std::vector&lt;float&gt;&gt;(999));
    std::vector&lt;std::vector&lt;std::vector&lt;float&gt;&gt;&gt; b_score;
    b_score.push_back(std::vector&lt;std::vector&lt;float&gt;&gt;(999));
    std::vector&lt;std::vector&lt;std::vector&lt;float&gt;&gt;&gt; b_groups;
    for (int i = 0; i &lt; dataset[0].size(); i++) {
        for (int j = 0; j &lt; dataset.size(); j++) {
            std::vector&lt;std::vector&lt;std::vector&lt;float&gt;&gt;&gt; groups = test_split(i, dataset[j][i], dataset); // gets the split of the dataset (assigns each vector in the dataset to either 'left' or 'right')
            float gini = gini_index(class_values, groups); // calculates the gini
            if (gini &lt; b_score[0][0][0]) {
                b_index[0][0][0] = i;
                b_value[0][0][0] = dataset[j][i];
                b_score[0][0][0] = gini;
                b_groups = groups;
            }
        }
    }
    std::vector&lt;std::vector&lt;std::vector&lt;std::vector&lt;float&gt;&gt;&gt;&gt; vals;
    vals.push_back(b_index);
    vals.push_back(b_value);
    vals.push_back(b_groups);
    return vals; // returns the values.
}

int main(void)
{
    std::vector&lt;std::vector&lt;float&gt;&gt; dataset;

    std::vector&lt;std::vector&lt;std::vector&lt;std::vector&lt;float&gt;&gt;&gt;&gt; result = get_split(dataset);

    return fgetc(stdin);
}


Now you need to workout where it is crashing, easy in Visual Studio but very difficult on an Arduino.  However I would look at simplifying the code too.