2016-06-12 104 views
-1

首先我想为我的大代码道歉。我试图保持它的结构,但我仍然不熟悉C++编程。Linux(g ++)中的分段错误,但Mac OS上没有。

我在OSX上创建了一个C++算法,它工作得很好。我需要在Linux上运行这个程序。编译Linux上没有给出错误,但是当我运行它,它提供了以下错误:

Segmentation fault (core dumped) 

我是新手调试代码,并试图与GDB调试它,但我不知道我应该如何继续。信息GDB给出如下:

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; 

我已经添加下面的代码,它由一个主文件c2f.cpp,头文件c2f.hpp和附加文件,其中我的商店功能c2f_functions.cpp

错误似乎发生当我通过3 名单参照一个名为c2f_functions功能。此功能位于c2f_functions.cpp脚本内。

我的问题是,

  1. 我怎么能解决这个问题?
  2. 为什么它在OSX下运行良好,但不在Linux下运行?

很多thnaks!

主文件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); 

头文件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); } 

功能文件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; 
    //=============================================================================// 

} 

    //*****************************************************************************// 
    //*****************************************************************************// 
+1

未定义行为的典型symptopm。 –

+0

首先要做的是在gdb中输入'bt'来获得回溯,这样你就可以看到你是如何到达错误的位置的。第二件事是学习更多关于gdb ;-) –

回答

1

我不知道,但我怀疑的问题是,你删除一个迭代器,接着,使用(增量)它。

以下为关键的部分

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); 
    } 
    } 

当你erase(iter_new)iter_new成为指向一个无效的对象的迭代器;递增它(iter_new++)给你(如果我没有错)一个未定义的值和以下iter_new->x可以分段错误你的程序。

我想,一个解决方案可以使用后缀增量调用erase()使erase()通话iter_newiter_new副本递增到调用erase()之前的有效迭代的;像

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:对不起,我的英语不好

+0

非常感谢,这有助于修复我的代码。问题的确在于删除'iter_new'。由于我只需删除一个项目,我最终做的是在删除iter_new后添加一个“break”。通过这种方式,当项目被删除时,第二个for循环(我打破的那个循环)再次重新开始,并且迭代器再次重新开始,因此'iter_new'不能再指向无效对象。非常感谢您付出努力回答我的问题! – user2835098

2

SYSSEGV分段错误是由于尝试访问程序允许区域以外的内存引起的。在这种情况下,iter_old或iter_new未初始化或包含与程序内存区域不对应的值。

它可能会崩溃在一个计算机系统,而不是另一个,因为1)不同的系统可具有在未初始化的变量的不同值和2)不同的系统不同地限定计划可用内存。

总之,寻找与SEGV错误坏指针值,并且知道错误可以在不同的系统不同的方式出现。

+0

这个问题确实存在于'iter_new'中。正如@max66指出的那样,当'iter_new'被删除时,它会变成一个指向无效对象的迭代器。我通过在删除项目之后添加一个'break'来解决这个问题,以便退出for循环并重新初始化迭代器。非常感谢您花时间回答我的问题。 – user2835098