0

I have implemented a simple code which simulates cell life. For some cases it works fine, but for others, it gives a SIGABRT out of range error in line 72(as highlighted). The code essentially takes a vector of cell numbers as input. Then it creates two new vectors, celllife and time vectors, in which it stores the lifetime of the cell and the time elapsed to compare the cell's life. For example, if cell life vectors are

{2, 3, 4, 1, 2}

and time vector's element's are:

{0, 1, 2, 0, 1}

it means that cell 1 has a lifetime of 2 but 0 seconds have elasped for it, and so on. The program prints the total number of cells each second, and terminates when all the cells die i.e the time vector values are more than celllife values. the expected output should look something like this:

[Main] Input gene seeds: 2 10 18 26 34 66
Monitor: Total cells: 0 [0 s]
Monitor: Total cells: 6 [1 s]
Monitor: Total cells: 24 [2 s]
Monitor: Total cells: 18 [3 s]
Monitor: Total cells: 0 [4 s]

but because of the error, it only reaches till the second-last line:

[Main] Input gene seeds: 2 10 18 26 34 66
Monitor: Total cells: 0 [0 s]
Monitor: Total cells: 6 [1 s]
Monitor: Total cells: 24 [2 s]
Monitor: Total cells: 18 [3 s]

Any suggestions for fixing the error will be greatly appreciated!

// code
#include <iostream>
#include <bits/stdc++.h> 
#include <thread>
#include <string>
#include <sstream>
#include<vector>
#include <chrono>
#include <mutex>
#include <stdlib.h>
using namespace std;
vector<int> inputs;
vector<thread> threads;
vector<int>childcells;
vector<int>celllife;
vector<int>cellvalues;
vector<int> timevector;
int laststrike= 0;
int newcell_lifetime;
//int counter;
int counter= 0;
int sum;
int main()
{   
    cout<<"[Main] Please input a list of gene seeds: "<<endl;
    //we get a line as string and pass them into the vector 'inputs'
    int value;
    string line;
    getline(cin, line);
    istringstream iss(line);
    while(iss >> value){

       inputs.push_back(value);
    }

    int total=0;
    int timer= 0;
    bool happening = true;
    cout<<"[Monitor] Started [ 0 s ]"<<endl;  //intial value of total cells
    while(happening == true){//this runs until the total value reaches zero
        int j=0;

        for (int unsigned  i = 0; i < inputs.size(); i++) {
            //traverses through every element in vector
            //the following are computations for calculating variables 'lifetime' and 
 'halflife' 
            int lifetime = (0.1+(inputs.at(i)%8));
            if (timer >= lifetime ){


                inputs.erase(inputs.begin() + i);

                i--;
                continue;
            }
            j=j+1;

            int halflife= lifetime/2;
                if (timer == halflife ){
                int newcell = inputs.at(i)/ 8;
                if(newcell != 0){
                //newcells=newcells+ newcell;
                childcells.push_back(newcell);
                celllife.push_back(lifetime);
                timevector.push_back(0);

                }//if halflife equals timer, the code inserts the new cell into the childcells vector and inserts a 0 value into the time vector
            }


        }



        int count=0;
        vector<int>::iterator it;
        for(it = celllife.begin(); it != celllife.end(); it++,count++ ){

                if (celllife.at(count) == timevector.at(count)) { //this is the line with the SIGABRT error
                    timevector.erase(timevector.begin() + count);
                    celllife.erase(celllife.begin() + count);
                    childcells.erase(childcells.begin() + count);

            }

            }
        counter++;
        sum= accumulate(childcells.begin(), childcells.end(), 0); 

        total=j+sum;

        timer=timer+1;
         cout<<"[Monitor] Total cells "<<total<<" [ " <<int(timer) <<" s ]"<<endl;

        for (int unsigned  k = 0;  k< timevector.size(); k++) {
            timevector.at(k)++;

        }//after one second, all timevector values are incremented
        if(total == 0){

            happening = false;
        }

    }

    return 0;

}
user840
  • 37
  • 5
  • Recommended reading: [Why should I not #include ?](https://stackoverflow.com/questions/31816095/why-should-i-not-include-bits-stdc-h) – user4581301 Dec 31 '19 at 00:21

1 Answers1

1
 celllife.erase(celllife.begin() + count);

Somewhere in your C++ book you will find an explanation that std::vector::erase will invalidate iterators that meet the following conditions:

Invalidates iterators and references at or after the point of the erase, including the end() iterator.

for(it = celllife.begin(); it != celllife.end(); it++,count++ ){

A closer examination of this for loop, with the above-referenced erase() call, shows that erase() will always erase the same value referenced by the it iterator, here. As such, after the erase() call this it will no longer be valid, and the incrementing the invalid it iterator, as part of the loop iteration expression, results in undefined behavior, and most certainly the reason for your crashes.

Sam Varshavchik
  • 114,536
  • 5
  • 94
  • 148