2013-10-19 69 views
1

我有兩個類(約會,計劃)和一個驅動程序(主)。訪問衝突(分段錯誤)

main.cpp中:

#include <iostream> 
#include "schedule.h" 
#include "appointment.h" 

using namespace std; 

int main() 
{ 
    schedule mySch2("hello"); 

    appointment myAppt(100002,"appointment",10,1,2013); 
    myAppt.printS(cout,2); 

    mySch2.addtoSchedule(myAppt); 


    system("PAUSE"); 
    return EXIT_SUCCESS; 
} 

schedule.h

#ifndef SCHEDULE_H 
#define SCHEDULE_H 

#include<iostream> 
#include "appointment.h" 

using namespace::std; 
const int SCH_ENTRIES = 10; 
class schedule 
{ 
     public: 
      schedule(void); 
      schedule(const char *p); 
      bool addtoSchedule(const appointment &); 

     private: 
       char title[40]; 
       int count; 
       appointment appointmentArray[SCH_ENTRIES]; 
}; 
#endif 

schedule.cpp

#include "schedule.h" 
#include "appointment.h" 
#include <iostream> 

using namespace::std; 

schedule::schedule(void) 
{ 
} 
schedule::schedule(const char *p) 
{ 
    strcpy(title, p); 
    count = 0; 
    cout << title << endl; 
    cout << count << endl; 
    cout << "----" << endl; 
} 

bool schedule::addtoSchedule(const appointment & myAppt) 
{ 
    cout << appointmentArray[0].getDay(); 
    return false; 
} 

appointment.h(我沒有寫這個,這是提供) - 對於這個問題不是非常重要的

#ifndef APPOINTMENT_H 
#define APPOINTMENT_H 

    #include <fstream> 
    #include <cstring> 

    using std::ostream; 

    // The Designer decides upon the following data and actions (i.e. Functions) 
    // and places the class in the file appointment.h 

    class appointment 
    { 
     public: 

      appointment(void);            // default constructor 
      appointment(long, const char [],int d, int m, int y);   // 5 argument constructor 
      appointment(const appointment &);        // copy constructor 

      void keyBoardInput(void);          // Assume no blanks in the desc 

      long getSource(void) const;          // return source 
      void setSource(long);           // change source 

      void setMonth(int); 
      void setDay(int); 
      void setYear(int); 

      int getMonth(void) const; 
      int getDay(void) const; 
      int getYear(void) const; 

      const char *getDescription(void) const;       // return the address of the description 
      void changeDescription(const char *) ;       // change an existing description 

      void copyTo(appointment &) const;        // copy invoking instance to parameter 

      void incrementDate (void);          // advance the date by ONE day 
                      // You can assume 30 days in each month 

      void printS(ostream &, int dateFormat) const; // print all fields 
      // dateFormat == 1 month/day/year 
      // dateFormat == 2 day/month/year 

      ~appointment();    // destructor - indicate the address 
              // of the variable that is leaving 

      private: 

      void setDescription(const char *); // used to allocated memory 

      // data 
      long source;   // id of the person scheduling the appointment 
      char * desc;   // description of the appointment - Dynamic Data 

      int day;    // day, month, and year when the appointment 
      int month;   // will happen 
      int year; 
    }; 

#endif 

appointment.cpp(我沒有寫這個,這是提供) - 對於這個問題

#include "appointment.h" 

#include <iostream> 

using std::cin; 
using std::cout; 

appointment::appointment() 
{ 
    day = 0; 
    cout << "default appt\n"; 
} 

appointment::appointment(long lSource, const char cDescription[], int d, int m, int y) 
{ 
    source = lSource; 
    day = d; 
    month = m; 
    year = y; 
    setDescription(cDescription); 
} 
appointment::appointment(const appointment & aToCopy) 
{ 
    source = aToCopy.getSource(); 
    day = aToCopy.getDay(); 
    month = aToCopy.getMonth(); 
    year = aToCopy.getYear(); 
    setDescription(aToCopy.getDescription()); 
} 


void appointment::setDescription(const char * cSource) 
{ 
    if (desc != NULL) free (desc); 

    if (cSource == NULL) 
     return; 

    desc = (char *)malloc (strlen (cSource) + 1); 
    strcpy(desc, cSource); 
} 

long appointment::getSource(void) const 
{ 
    return source; 
} 

void appointment::setSource(long lSource) 
{ 
    source = lSource; 
} 

void appointment::setMonth(int iMonth) 
{ 
    month = iMonth; 
} 

void appointment::setDay(int iDay) 
{ 
    day = iDay; 
} 

void appointment::setYear(int iYear) 
{ 
    year = iYear; 
} 

int appointment::getMonth(void) const 
{ 
    return month; 
} 

int appointment::getDay(void) const 
{ 
    return day; 
} 

int appointment::getYear(void) const 
{ 
    return year; 
} 

//return the address of the description 
const char * appointment::getDescription(void) const 
{ 
    return desc; 
} 

//change an existing description 
void appointment::changeDescription(const char * cDescription) 
{ 
    setDescription(cDescription); 
} 

void appointment::copyTo(appointment &p) const 
{ 
    p.source = source; 
    p.day = day; 
    p.month = month; 
    p.year = year; 
    p.setDescription(desc); 
} 

void appointment::incrementDate(void) 
{ 
    int days; 

    switch (month) 
    { 
     case 1: // Jan: 31 Days 
     case 3: // Mar: 31 Days 
     case 5: // May: 31 Days 
     case 7: // Jul: 31 Days 
     case 10: // Oct: 31 Days 
     case 12: // Dec: 31 Days 
      days = 31; 
      break; 

     case 4: // Apr: 30 
     case 6: // Jun: 30 
     case 8: // Aug: 30 
     case 9: // Sep: 30 
     case 11: // Nov: 30 
      days = 30; 
      break; 

     case 2: // Feb: 28/29 Days (Depends on year modulus 4 a modulus 100). 
      days = !(year % 4) || !(year % 100) ? 29 : 28; 
      break; 
    } 

    day++; 

    if (day > days) 
    { 
     month++; 
     day = 1; 

     if (month > 12) 
     { 
      month = 1; 
      year++; 
     } 
    } 
} 

void appointment::printS(ostream &out, int dateFormat) const 
{ 
    if (dateFormat == 1) 
    { 
     out << month << "/" << day << "/" << year << "\n"; 
    } 
    else if (dateFormat == 2) 
    { 
     out << day << "/" << month << "/" << year << "\n"; 
    } 
    else 
     out << "Unsupported dateFormat parameter specified (should be 1 or 2)."; 
} 

appointment::~appointment() 
{ 
    if (desc != NULL) 
    { 
     free (desc); 
     desc = NULL; 
    } 
} 

void appointment::keyBoardInput() 
{ 
    char temp[1024]; 

    cout << "Please type the description: "; 
    cin.getline (temp, sizeof(temp) - 1, '\n'); 
    cout << std::endl; 

    setDescription(temp); 
} 

當主驅動程序調用mySch2.addtoSchedule(myAppt)出現錯誤我不是超級重要的;

如果我取消日程scheduleArray [0] .getDay()內的行的註釋,然後一切運行並正常工作,沒有分段錯誤。只要該行沒有註釋,它就會在運行時引發錯誤(在崩潰之後,我進入調試器並逐步執行程序)。

+0

程序的其他部分必須破壞內存。分段違規是由指針濫用引起的,並且您沒有在代碼的該部分中使用任何指針。你有沒有嘗試過使用valgrind來捕捉內存問題? – Barmar

+0

這是整個代碼:(我不知道valgrind是什麼 –

+0

Valgrind是一個調試內存管理問題的工具,這正是你所擁有的。 – Barmar

回答

0

在調用setDescription之前,您從未初始化descnullptr以獲得類appointment。這發生在兩個構造函數中。學習使用初始化程序列表:

appointment::appointment() 
    : source(), desc(), day(), month(), year() 
{ 
    cout << "default appt\n"; 
} 

appointment::appointment(long lSource, const char cDescription[], int d, int m, int y) 
    : source(lSource), desc(), day(d), month(m), year(y) 
{ 
    setDescription(cDescription); 
} 

appointment::appointment(const appointment & aToCopy) 
    : source(aToCopy.getSource()) 
    , desc() 
    , day(aToCopy.getDay()) 
    , month(aToCopy.getMonth()) 
    , year(aToCopy.getYear()) 
{ 
    setDescription(aToCopy.getDescription()); 
} 

爲什麼錯?

沒有初始化的desc的價值是不確定的,因此未定義行爲提領,當然這樣傳遞給free

void appointment::setDescription(const char * cSource) 
{ 
    if (desc != NULL) free (desc); // desc contains non-null garbage. 

    if (cSource == NULL) 
     return; 

    desc = (char *)malloc (strlen (cSource) + 1); 
    strcpy(desc, cSource); 
} 

也就是說,我強烈建議使用std::string來代替。它會使這個類的複製consructor完全消失,並且默認的構造函數不重要。

約在保留C++程序使用malloc(),作爲意見建議都是,但是打不死已經在此論壇(我用TE流行的觀點一致)。

+0

唉唉,正如我所說的約會類是提供了,所以我真的沒有想到它看上去太強烈。雖然,將其設置爲null真的從沒想過我的腦海裏無論是。我感謝所有的幫助和解釋,以及我也會檢查更多的std :: string,因爲你提到它,因爲它是我還沒有很多經驗的東西(我仍然是新的C++,並在印象向量更好?我'我只是看着他們倆)!不是我有多少能夠偏離所提供的代碼,但設置爲null解決了問題,所以我再次超級開心^ _^ty –