2017-02-10 21 views
-1

私はC++を学び始めました。私は学生で、私はここでワークショップを持っています。既存のプログラムにコンストラクタを設計して実装するという考えはです。私はすべてのエラーを修正しましたが、今度はがコンパイルされ、セグメンテーションフォールト(コアダンプされた)が与えられます。私は何が間違っているのか分かりません。私は変更することができますpassenger.hpassenger.cpp。誰かがコードを見てください。エラーはどこで発生しましたか?どうすれば対処できますか?C++コンストラクタのセグメント化エラー(コアダンプ)

//passenger.h 
//TODO: add header guards here 
#ifndef _PASSENGER_H_ 
#define _PASSENGER_H_ 
// TODO: holiday namespace here 
namespace holiday{ 
    // TODO: declare the class Passenger here 
    class Passenger { 
     // TODO: add the class the attributes, 
     char m_name[32]; 
     char m_destination[32]; 
     int m_departureYear; 
     int m_departureMonth; 
     int m_departureDay; 
    public:  
     //  the member function already provided, 
     void display(bool onlyNames = false) const; 
     //  and the member functions that you must implement 
     Passenger(); 
     Passenger(const char pName[],const char pDestination[]); 
     bool isEmpty() const; 
     bool canTravelWith(const Passenger&) const; 
    }; 
} 
#endif 

-

//passenger.cpp 
// TODO: add your headers here 
#include "passenger.h" 
#include <iostream> 
#include <cstring> 
// TODO: add the namespaces that you will be using here 
using namespace std; 
// TODO: holiday namespace here 
namespace holiday{ 
    // TODO: add the default constructor here 
    Passenger::Passenger(){ 
     m_name[0] = '\0'; 
     m_destination[0] = '\0'; 
     m_departureYear = 0; 
     m_departureMonth = 0; 
     m_departureDay = 0; 
    } 
    // TODO: add the constructor with 2 parameters here 
    Passenger::Passenger(const char pName[],const char pDestination[]){ 
     //safe state 
     m_name[0] = '\0'; 
     m_destination[0]= '\0'; 
     m_departureYear = 0; 
     m_departureMonth = 0; 
     m_departureDay = 0; 
     //validation 
     if (pName[0] != 0 && pName != nullptr && 
      pDestination[0] != 0 && pDestination != nullptr){ 
       strcpy(m_name,pName); 
       strcpy(m_destination,pDestination); 
       m_departureYear = 2017;        
       m_departureMonth = 7; 
       m_departureDay = 1; 
     } 
    } 
    // TODO: add the canTravelWith(...) function here 
    bool Passenger::canTravelWith(const Passenger& pPassenger) const{ 
     bool _together; 
     if(m_departureYear == pPassenger.m_departureYear && 
      m_departureMonth == pPassenger.m_departureMonth && 
      m_departureDay == pPassenger.m_departureDay && 
      strcmp(m_destination, pPassenger.m_destination) == 0) {  
       _together = true;   
      } else { 
       _together = false; 
      } 
      return _together; 
    } 
    // TODO: add the isEmpty() function here 
    bool Passenger::isEmpty() const{ 
     bool _empty; 
     if (m_name[0] == '\0' && 
     m_destination[0] == '\0' && 
     m_departureYear == 0 && 
     m_departureMonth == 0 && 
     m_departureDay == 0){ 
      _empty = true; 
     } else { 
      _empty = false; 
     } 
     return _empty; 
    } 
    // below is the member function already provided 
    // TODO: read it and understand how it accomplishes its task 
    void Passenger::display(bool nameOnly) const 
    { 
     if (false == this->isEmpty()) 
     { 
      cout << this->m_name; 
      if (false == nameOnly) 
      { 
       cout << " will travel to " << this->m_destination << ". " 
        << "The journey will start on " 
        << this->m_departureYear << "-" 
        << this->m_departureMonth << "-" 
        << this->m_departureDay 
        << "." << endl; 
      } 
     } 
     else 
     { 
      cout << "Invalid passenger!" << endl; 
     } 
    } 

}//holiday 

- あなたが持っているあなたのコードで

//main.cpp 
#include <iostream> 
#include "passenger.h" 
#include "passenger.h" // this is intentional 

using namespace std; 
using namespace holiday; 

int main() 
{ 
    Passenger travellers[] = { 
     Passenger(nullptr, "Toronto"), 
     Passenger("", "Toronto"), 
     Passenger("John Smith", nullptr), 
     Passenger("John Smith", ""), 
     Passenger("John Smith", "Toronto"), // valid 
     Passenger(nullptr, nullptr), 
     Passenger() 
    }; 
    cout << "----------------------------------------" << endl; 
    cout << "Testing the validation logic" << endl; 
    cout << "(only passenger 5 should be valid)" << endl; 
    cout << "----------------------------------------" << endl; 
    for (unsigned int i = 0; i < 7; ++i) 
    { 
     cout << "Passenger " << i + 1 << ": " << (travellers[i].isEmpty() ? "not valid" : "valid") << endl; 
    } 
    cout << "----------------------------------------" << endl << endl; 

    Passenger vanessa("Vanessa", "Paris"), 
       mike("Mike", "Tokyo"), 
       alice("Alice", "Paris"); 

    cout << "----------------------------------------" << endl; 
    cout << "Testing the display function" << endl; 
    cout << "----------------------------------------" << endl; 
    vanessa.display(); 
    mike.display(); 
    alice.display(); 
    cout << "----------------------------------------" << endl << endl; 

    cout << "----------------------------------------" << endl; 
    cout << "Testing the travelling together logic" << endl; 
    cout << "----------------------------------------" << endl; 
    cout << "Can Vanessa and Mike travel together (should be NO)? " 
     << (vanessa.canTravelWith(mike) ? "YES" : "NO") << endl; 
    cout << "Can Vanessa and Alice travel together (should be YES)? " 
     << (vanessa.canTravelWith(alice) ? "YES" : "NO") << endl; 
    cout << "Can Alice and Vanessa travel together (should be YES)? " 
     << (alice.canTravelWith(vanessa) ? "YES" : "YES") << endl; 
    cout << "Can Mike and Alice travel together (should be NO)? " 
     << (mike.canTravelWith(alice) ? "YES" : "NO") << endl; 
    cout << "----------------------------------------" << endl << endl; 


    return 0; 
} 
+1

CとC++は異なる言語です。関連する言語タグのみを使用してください。 – kaylum

+2

これは問題ではありませんが、アンダースコアで始まり大文字( '_PASSENGER_H_')が続く名前と2つの連続したアンダースコアを含む名前は、実装で使用するために予約されています。あなたのコードでそれらを使用しないでください。 –

答えて

1

:呼び出し側がちゃっかり(意図的に)あなたはnullはpName渡すこと

if (pName[0] != 0 && pName != nullptr && 
     pDestination[0] != 0 && pDestination != nullptr){ 

注意およびpDestination。

条件の短絡については、これらのチェックを実行する順序を変更する必要がある場合に実行してください。


これとは別に重要なことに、member initialization listsを調べるとよいでしょう。

+0

すべてが意味を成しています。情報をいただきありがとうございます!ルール#1は常にnullptrをチェックします! –

0

pName[0] != 0 && pName != nullptrのようなテストの順序が間違っています。最初にpNameがヌルかどうかを確認する必要があります。呼び出し元がnullptrを渡すので、pNameがnullでないことを確認する前にpName[0]にアクセスすると、未定義の動作が発生します。

+0

うん、それはうまくいった!ありがとうございました! –

関連する問題