输出单元格值的简单代码会在 C++ 中产生运行时 SIGABRT 错误
simple code outputting cell values gives a runtime SIGABRT error in C++
我实现了一个模拟细胞寿命的简单代码。对于某些情况,它工作正常,但对于其他情况,它会在第 72 行(如突出显示)中给出 SIGABRT 超出范围错误。该代码实质上将单元格编号向量作为输入。然后它创建了两个新的向量,celllife 和 time 向量,其中它存储了单元格的生命周期和经过的时间,以比较单元格的寿命。例如,如果细胞生命向量是
{2, 3, 4, 1, 2}
时间向量的元素是:
{0, 1, 2, 0, 1}
这意味着单元格 1 的生命周期为 2,但已经过去了 0 秒,依此类推。该程序每秒打印细胞总数,并在所有细胞死亡时终止,即时间向量值大于 celllife 值。预期输出应如下所示:
[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]
但由于错误,它只到达倒数第二行:
[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]
如有任何修复错误的建议,我们将不胜感激!
// 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;
}
celllife.erase(celllife.begin() + count);
在你的 C++ 书中的某个地方你会找到这样的解释 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++ ){
通过上面引用的 erase()
调用仔细检查此 for
循环,表明 erase()
将始终删除 it
引用的相同值迭代器,在这里。因此,在 erase()
调用后,此 it
将不再有效,并且递增无效的 it
迭代器作为循环迭代表达式的一部分,会导致未定义的行为,并且大多数肯定是你崩溃的原因。
我实现了一个模拟细胞寿命的简单代码。对于某些情况,它工作正常,但对于其他情况,它会在第 72 行(如突出显示)中给出 SIGABRT 超出范围错误。该代码实质上将单元格编号向量作为输入。然后它创建了两个新的向量,celllife 和 time 向量,其中它存储了单元格的生命周期和经过的时间,以比较单元格的寿命。例如,如果细胞生命向量是
{2, 3, 4, 1, 2}
时间向量的元素是:
{0, 1, 2, 0, 1}
这意味着单元格 1 的生命周期为 2,但已经过去了 0 秒,依此类推。该程序每秒打印细胞总数,并在所有细胞死亡时终止,即时间向量值大于 celllife 值。预期输出应如下所示:
[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]
但由于错误,它只到达倒数第二行:
[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]
如有任何修复错误的建议,我们将不胜感激!
// 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;
}
celllife.erase(celllife.begin() + count);
在你的 C++ 书中的某个地方你会找到这样的解释 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++ ){
通过上面引用的 erase()
调用仔细检查此 for
循环,表明 erase()
将始终删除 it
引用的相同值迭代器,在这里。因此,在 erase()
调用后,此 it
将不再有效,并且递增无效的 it
迭代器作为循环迭代表达式的一部分,会导致未定义的行为,并且大多数肯定是你崩溃的原因。