Reputation: 175
First of all I would like to apologize for my large code. I tried to keep it structured, but I am still new to programming in C++.
I created a C++ algorithm on OSX and it worked just fine. I need to run this program on Linux however. Compiling on Linux gave no errors, however when I run the program it gives the following error:
Segmentation fault (core dumped)
I am a newbie in debugging code and have tried to debug it with gdb, but I don't know how I should continue. The information gdb gives is the following:
c2f_function(new_candidates2, old_candidates, feature_list);
(gdb)
Program received signal SIGSEGV, Segmentation fault.
0x0000000000403dc5 in c2f_function (new_candidates=std::list = {...}, old_candidates=std::list = {...},
feature_list=empty std::list) at /home/martin/emc/group4/src/c2f_function.cpp:36
36 norm = iter_old->x -iter_new->x;
I have added the code below, it consists of a main file c2f.cpp, a header file c2f.hpp and an additional file where I store functions c2f_functions.cpp.
The error seems to happen when I pass 3 lists by reference to a function called c2f_functions. this function is within the c2f_functions.cpp script.
My questions are,
Many thnaks!
MAIN FILE c2f.cpp:
#include "c2f.hpp"
#include "c2f_function.cpp"
int main()
{
// define variables
double x, y;
// create old candidates list
list<Candidate> old_candidates;
// create new candidates list
list<Candidate> new_candidates1;
list<Candidate> new_candidates2;
list<Candidate> new_candidates3;
// create new features list
list<Candidate> feature_list;
//=============================================================================//
// LOAD FIRST DATA SET
//-----------------------------------------------------------------------------//
ifstream file1_("newcandidates_it0.txt");
if (file1_.is_open())
{
cout << "Reading file...1 " << endl;
while( file1_ >> x >> y)
{
// cout << x << "," << y << endl;
new_candidates1.push_back(Candidate(x , y));
}
file1_.close();
}
else {cout << "file is not open";}
//=============================================================================//
c2f_function(new_candidates1, old_candidates, feature_list);
//=============================================================================//
// LOAD SECOND DATA SET
//-----------------------------------------------------------------------------//
ifstream file2_("newcandidates_it1.txt");
if (file2_.is_open())
{
cout << "Reading file...2 " << endl;
while( file2_ >> x >> y)
{
// cout << x << "," << y << endl;
new_candidates2.push_back(Candidate(x , y));
}
file2_.close();
}
else {cout << "file is not open";}
//=============================================================================//
c2f_function(new_candidates2, old_candidates, feature_list);
HEADER FILE c2f.hpp
# include <iostream>
# include <stdlib.h>
# include <string>
# include <math.h>
# include <Eigen/Dense>
# include <cstdio>
# include <cstdlib>
# include <list>
# include <fstream>
# include <algorithm>
// # include <cstdarg>
using namespace std;
using namespace Eigen;
// correspondence margin: new point must lie w/i 10cm from old point
# define CORR_MARGIN 0.1
# define PERSIST_UB 3
# define PERSIST_LB -PERSIST_UB
class Candidate
{
public:
int id;
double x;
double y;
int persistency = 0;
int pflag = 0; // persistency flag
Candidate ( double xNew, double yNew ): x(xNew), y(yNew){}
void increasePersistency()
{
if (persistency < PERSIST_UB) // bound persistency from above
persistency++;
}
void decreasePersistency()
{
if (persistency > PERSIST_LB) // bound persistency from below
persistency--;
}
// bool operator< (const Candidate& right) const { return id < right.id; }
};
bool ascendingId ( Candidate a, Candidate b)
{
return a.id < b.id;
}
bool descendingId ( Candidate a, Candidate b)
{
return a.id > b.id;
}
bool ascendingPersistency ( Candidate a, Candidate b)
{
return a.persistency < b.persistency;
}
bool descendingPersistency ( Candidate a, Candidate b)
{
return a.persistency > b.persistency;
}
bool ascendingPflag ( Candidate a, Candidate b)
{
return a.pflag < b.pflag;
}
bool descendingPflag ( Candidate a, Candidate b)
{
return a.pflag > b.pflag;
}
bool sameId_Feature (Feature first, Feature second)
{ return first.id == second.id; }
bool samePflag (Candidate first, Candidate second)
{ return first.persistency == second.persistency; }
bool finder (Candidate first, Candidate second)
{return first.id == second.id;}
bool not_persistent (Candidate &a)
{ return (a.persistency==PERSIST_LB); }
Functions File c2f_function.cpp
void print_list(list<Candidate> &list2print)
{
for (auto const &iter : list2print)
{
cout << iter.x
<< "," << iter.y
<< " with id "
<< iter.id
<< " and persistency "
<< iter.persistency
<< endl;
}
}
void c2f_function(list<Candidate> &new_candidates, list<Candidate> &old_candidates, list<Candidate> &feature_list)
{
double norm;
//=============================================================================//
// CHECK FOR CORRESPONDENCE
//-----------------------------------------------------------------------------//
// Check if old candidates exist (initialization purposes)
if (old_candidates.empty() == 0) // old candidates exist
{
// Check Correspondence
for (auto iter_old = old_candidates.begin(); iter_old != old_candidates.end(); iter_old++)
{
// int persistency_upd_flag = 0;
for (auto iter_new = new_candidates.begin(); iter_new != new_candidates.end(); iter_new++)
{
// compute the norm between old_candidates and new_candidates
// norm = sqrt( pow(iter_old->x - iter_new->x, 2.0) + pow(iter_old->y - iter_new->y, 2.0));
norm = iter_old->x -iter_new->x;
if (norm <= CORR_MARGIN)
{
// Update position of old entry and increase persistency
iter_old -> x = iter_new->x;
iter_old -> y = iter_new->y;
iter_old -> increasePersistency();
// flag an update;
iter_old -> pflag = 1;
// remove list entry that has been coupled
new_candidates.erase(iter_new);
}
}
}
}
else
{
back_insert_iterator<list<Candidate>> it(old_candidates);
for (auto const &iter : new_candidates)
{
it = iter;
}
int counter=1;
for (auto iter = old_candidates.begin(); iter!= old_candidates.end(); iter++)
{
iter -> id = counter;
++counter;
}
cout << "initializing data set" << endl;
cout << endl << "====================================================" << endl;
return;
}
//=============================================================================//
//=============================================================================//
// DECREASE PERSISTENCY FOR NON-VIEWED CANDIDATES
//-----------------------------------------------------------------------------//
// remove persistency to non-associated candidates
old_candidates.sort(ascendingPflag);
for (auto iter = old_candidates.begin(); iter!= old_candidates.end(); iter++)
{
if ( iter -> pflag == 0 )
{
iter -> decreasePersistency();
find_if (feature_list.begin(), feature_list.end(),
[iter] (Candidate &item)
{
if (item.id == iter->id)
{
item.persistency = iter->persistency;
return true;
}
else return false;
}
);
}
// reset pflags
iter -> pflag = 0;
}
//=============================================================================//
//=============================================================================//
// ADD id TO REMAINING new_candidates LIST
//-----------------------------------------------------------------------------//
// get new id
old_candidates.sort(descendingId);
int new_id = old_candidates.begin() -> id + 1;
// add id to added items to old_candidates
for (auto iter = new_candidates.begin(); iter!= new_candidates.end(); iter++)
{
iter -> id = new_id;
new_id++;
}
//=============================================================================//
//=============================================================================//
// MERGE REMAINING new_candidates WITH old_candidates LIST
//-----------------------------------------------------------------------------//
old_candidates.splice(old_candidates.end(), new_candidates);
//=============================================================================//
//=============================================================================//
// ADD TO feature_list
// REMOVE FROM feature_list
// REMOVE FROM old_list
//-----------------------------------------------------------------------------//
// removing from old_candidates when persistency @ lower bound
old_candidates.sort(ascendingPersistency);
for (auto const &iter_old : old_candidates)
{
if (iter_old.persistency == PERSIST_LB)
{
old_candidates.pop_front();
}
else
{break;}
}
// removing from feature_list when persistency @ lower bound
feature_list.sort(ascendingPersistency);
for (auto const &iter_feat : feature_list)
{
if (iter_feat.persistency == PERSIST_LB)
{
feature_list.pop_front();
}
else
{break;}
}
// sorting
old_candidates.sort(descendingPersistency);
// adding
back_insert_iterator<list<Candidate>> it(feature_list);
// define counter
int counter;
for (auto const &iter_old : old_candidates)
{
counter =0;
if (iter_old.persistency == PERSIST_UB)
{
if (feature_list.size()>0)
{
for (auto iter_feat = feature_list.begin(); iter_feat != feature_list.end(); iter_feat++)
{
if (iter_feat->id == iter_old.id)
{
iter_feat->x = iter_old.x;
iter_feat->y = iter_old.y;
iter_feat->persistency = iter_old.persistency;
counter = 0;
break;
}
else
{
counter++;
}
}
if (counter >0)
{
it = iter_old;
}
}
else
it = iter_old;
}
else
{
break;
}
}
//=============================================================================//
//=============================================================================//
// DISPLAY FEATURE LIST
//-----------------------------------------------------------------------------//
if (feature_list.size() > 0)
{
feature_list.sort(ascendingId);
cout << "Feature members" << endl;
print_list(feature_list);
cout << endl << "====================================================" << endl;
}
else
cout << endl << "====================================================" << endl;
//=============================================================================//
}
//*****************************************************************************//
//*****************************************************************************//
Upvotes: 0
Views: 2129
Reputation: 66230
I'm not sure but I suspect the problem is that you erase an iterator and, next, you use (increment) it.
The following is the crucial part
for (auto iter_new = new_candidates.begin(); iter_new != new_candidates.end(); iter_new++)
{
norm = iter_old->x -iter_new->x;
if (norm <= CORR_MARGIN)
{
// [...]
new_candidates.erase(iter_new);
}
}
When you erase(iter_new)
, iter_new
become an iterator pointing to an invalid object; incrementing it (iter_new++
) give you (if I'm not wrong) an undefined value and the following iter_new->x
can segmentation fault your program.
I suppose that a solution can be the use of the postfix increment calling erase()
so that erase()
call a copy of iter_new
and iter_new
is incremented to a valid iterator before the call to erase()
; something like
auto = new_candidates.begin();
while ( iter_new != new_candidates.end() )
{
norm = iter_old->x -iter_new->x;
if (norm <= CORR_MARGIN)
{
// [...]
new_candidates.erase( iter_new++ );
}
else
++iter_new;
}
p.s.: sorry for my bad English
Upvotes: 1
Reputation: 4207
SYSSEGV Segmentation Fault is caused by an attempt to access memory outside of the program's allowed area. In this case, either iter_old or iter_new is not initialized or contains a value that does not correspond to the program's memory area.
It may crash on one computer system and not on another because 1) different systems can have different values in uninitialized variables and 2) different systems define the programs available memory differently.
In short, look for bad pointer values with SEGV errors, and know that bugs can appear in different ways on different systems.
Upvotes: 4