2016-06-12 17 views
-1

まず大きなコードをお詫び申し上げます。私はそれを構造化したままにしようとしましたが、私はまだC++でプログラミングするのが初めてです。Linux(Mac OS)ではセグメンテーションフォルトが発生しています(g ++)。

私はOSXでC++アルゴリズムを作成しましたが、うまくいきました。私はLinux上でこのプログラムを実行する必要があります。私はデバッグコードで初心者ですとGDBでそれをデバッグしようとしましたが、私は知らない

Segmentation fault (core dumped) 

:私はプログラムを実行すると、Linux上でコンパイルすると、エラーを与えていない、しかし、それは次のエラーを与えます私はどのように続けるべきですか? 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及びI追加のファイルで構成されストア機能c2f_functions.cpp。私はc2f_functions呼び出された関数を参照することにより、3 リストを渡すとき

エラーが発生するようです。この機能は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

私は確かではありませんが、あなたはイテレータを消去し、次にそれを(インクリメントして)使用するという問題があると思われます。

あなたerase(iter_new)iter_newが無効なオブジェクトを指すイテレータになった場合、次は

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

重要な部分です。それをインクリメントすると(iter_new++)、あなたに(私が間違っていないなら)未定義の値が与えられ、次のようにiter_new->xはあなたのプログラムにセグメント違反を起こすことがあります。

私は解決策がerase()コールがiter_newiter_newのコピーがerase()を呼び出す前に、有効なイテレータにインクリメントされるように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'を追加しました。この方法でアイテムが削除されると、2回目のforループ(私が壊れたもの)がやり直され、イテレータがやり直されるので、 'iter_new'は無効なオブジェクトを指し示すことができなくなります。私の質問に答える努力をしてくれてありがとう、もう一度ありがとう! – user2835098

2

SYSSEGVセグメンテーションフォルトは、プログラムの許可領域外のメモリにアクセスしようとした場合に発生します。この場合、iter_oldまたはiter_newは初期化されていないか、プログラムのメモリー領域に対応しない値を含んでいます。

1)異なるシステムが初期化されていない変数に異なる値を有することができ、2)異なるシステムが異なるプログラムの利用可能なメモリを定義するので、それは、1つのコンピュータ・システム上ではなく、他にクラッシュすることがあります。要するに

、SEGVエラーが発生した不正なポインタ値を探し、そしてバグが異なるシステム上の異なる方法で表示されることができることを知っています。

+0

問題は本当に 'iter_new'にあったのです。 @ max66が指摘したように、 'iter_new'が削除されると、それは無効なオブジェクトを指すイテレータになります。これを解決するには、アイテムを削除した後に 'break'を追加してforループから抜け出し、イテレータを再初期化してください。私の質問に答える時間をとってくれてありがとう、ありがとう。 – user2835098

関連する問題