1

When I call a function, get_split(), the Arduino restarts. I have tried to find what is causing this, but I have had no luck. Here is my code:

std::vector<std::vector<std::vector<std::vector<float>>>> get_split(std::vector< std::vector< float > >& dataset) {
  std::vector<int> class_values; // declares vector 'class_values'
  for (int i = 0; i < 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<std::vector<std::vector<float>>> b_index;
  b_index.push_back(std::vector<std::vector<float>>(999));
  std::vector<std::vector<std::vector<float>>> b_value;
  b_value.push_back(std::vector<std::vector<float>>(999));
  std::vector<std::vector<std::vector<float>>> b_score;
  b_score.push_back(std::vector<std::vector<float>>(999));
  std::vector<std::vector<std::vector<float>>> b_groups;
  for (int i = 0; i < dataset[0].size(); i++) {
    for (int j = 0; j < dataset.size(); j++) {
      std::vector<std::vector<std::vector<float>>> 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 < 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<std::vector<std::vector<std::vector<float>>>> vals;
  vals.push_back(b_index);
  vals.push_back(b_value);
  vals.push_back(b_groups);
  return vals; // returns the values.
}

This code is meant to check the gini of splitting a certain function (the gini_index() function works fine). Then it calls test_split which assigns the vector values into two sub-vectors in the vector groups, left and right. Then I just choose the split with the lowest gini.

When I delete everything in the function it doesn't restart, but I have deleted the first for loop, and also the part where it returns a vector, but still no luck. Also when deleting the for loop underneath the declaration of b_groups, it still doesn't work. I don't think it is a memory/storage issue because the Arduino IDE says that I'm only using 3% of that.

PS: I have used the library StandardCplusplus library to include vectors.

4
  • Have you tried calculating the cyclometric complexity of this code? It looks horrible. I think it is a memory issue, probably a segmentation violation. The order or you loops looks quite strange, the inner and then the outer. Have you tried running this on a desktop (Linux or Windows) to get some debug data. – Code Gorilla Apr 4 '17 at 10:44
  • I think this is a pure coding error, so you might get better feed back on Stackoverflow. – Code Gorilla Apr 4 '17 at 10:44
  • @Matt Okay - thanks. Sorry for asking this, but when you ask if I have tried running this on a desktop, what do you mean by that? Do you just want my to move my code to a desktop computer and upload it from there? – LucasBN86 Apr 4 '17 at 10:46
  • 1
    Please calculate the amount of memory you are allocating on the heap. My guess is that you have allocated more than the 8K byte available. Trim your data structures. Even the mega is a MCU. Program accordingly, i.e. with limited resources in mind. – Mikael Patel Apr 4 '17 at 11:12
2

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 <vector>

std::vector<std::vector<std::vector<float>>> test_split(const int& i, const float& f, std::vector< std::vector< float > >& dataset)
{
    std::vector<std::vector<std::vector<float>>> vals;
    return vals;
}

float gini_index(const std::vector<int>& class_values, const std::vector<std::vector<std::vector<float>>>& group)
{
    return 1.0f;
}

std::vector<std::vector<std::vector<std::vector<float>>>> get_split(std::vector< std::vector< float > >& dataset) {
    std::vector<int> class_values; // declares vector 'class_values'
    for (int i = 0; i < 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<std::vector<std::vector<float>>> b_index;
    b_index.push_back(std::vector<std::vector<float>>(999));
    std::vector<std::vector<std::vector<float>>> b_value;
    b_value.push_back(std::vector<std::vector<float>>(999));
    std::vector<std::vector<std::vector<float>>> b_score;
    b_score.push_back(std::vector<std::vector<float>>(999));
    std::vector<std::vector<std::vector<float>>> b_groups;
    for (int i = 0; i < dataset[0].size(); i++) {
        for (int j = 0; j < dataset.size(); j++) {
            std::vector<std::vector<std::vector<float>>> 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 < 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<std::vector<std::vector<std::vector<float>>>> 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<std::vector<float>> dataset;

    std::vector<std::vector<std::vector<std::vector<float>>>> 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.

Your bug

3
  • I couldn't do all the work for you :) – Code Gorilla Apr 4 '17 at 11:27
  • You might want to look at the line b_score.push_back(std::vector<std::vector<float>>(999)); I suspect that is where the problem is (and the two similar lines above) – Code Gorilla Apr 4 '17 at 11:43
  • 2
    Yes, that did turn out to be the issue. Thank you very much – LucasBN86 Apr 4 '17 at 11:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.