2017-02-10 29 views
-1

Недавно Я начал изучать C++. Я студент, и здесь у меня есть мастерская. Идея для проектирования и реализации конструкторов в существующей программе. Таким образом, я могу изменить только 2 файла из 3. Я исправил все ошибки, но теперь он компилирует и дает мне ошибку сегментации (core dumped). Я понятия не имею, что я делаю неправильно. Могу только изменить пассажир.h и пассажир.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_'), и имена, содержащие два последовательных символа подчеркивания, зарезервированы для использования реализацией. Не используйте их в своем коде. –

ответ

1

В коде у вас есть:

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

Обратите внимание, что вызывающий проницательно (намеренно) передает вам нулевой PNAME и pDestination.

Ознакомьтесь с условиями короткого замыкания и работы, если вам нужно изменить порядок выполнения этих проверок.


Отдельно, но не менее важно, вы можете захотеть взглянуть на member initialization lists.

+0

Все имеет смысл теперь, спасибо за информацию! правило # 1 всегда проверяет nullptr! –

0

Тестирование, как pName[0] != 0 && pName != nullptr, происходит в неправильном порядке. Вам нужно проверить, является ли сначала pName. Вызывающий абонент пропускает nullptr, поэтому, обращаясь к pName[0], перед тем, как проверить, что pName не является нулевым, дает неопределенное поведение.

+0

Да, это сработало! Спасибо! –