Утечка памяти в программе на C ++ - PullRequest
1 голос
/ 24 марта 2010

Спасибо, ребята, за каждый const char * я пошел дальше и заменил его на string. Еще раз спасибо!

Может кто-нибудь помочь, пожалуйста? : / ( Это не домашнее задание )

#include <iostream>
#include <string>
#include <vld.h>

using namespace std;

class Time
{
private:

    string dayTime;

    int hour,
        minute;

public:

    Time(int hour, int minute, string dayTime); // constructor
    Time(); // default constructor

    void setTime();

    // using encapsulation
    const int getHour()  const  { return hour;   };
    const int getMinte() const  { return minute; };
    string getDayTime() const  { return dayTime;  };

    const int incrementHours();
    int incrementMinutes();

    friend ostream& operator<<(ostream& out, const Time tObj); // to write the objects attributes
};

class Date
{

private:
    string  month;
    int     day,
            year;

public:

    Date(string month, int day, int year);
    Date(const Date& d);// copy constructor

    Date(); // default constructor
    virtual ~Date();

    void setDate();

    string getMonth()  const { return month; };
    const int getDay()  const { return day;  };
    const int getYear() const { return year; };

    friend ostream& operator<<(ostream& out, const Date dObj); // to write the objects attributes
};

class Event
{
private:

    string eventName,
           userEvent;

    struct node
    {
        node();
        node  * nextByName;
        string eventName;
    };

    node * headByName;

public:
    Event(string eventName, const Date &myDate);
    Event();

    virtual ~Event();

    void insert(string eventName, const Date &myDate, const Time &myTime);
    void setEvent();

    string getEvent() const { return userEvent; };
    void displayByName(ostream& out) const;

};

/***************************************************/

Time::Time(int hour, int minute,
           string dayTime) : minute(minute),
                             hour(hour),
                             dayTime(dayTime)

{
    this->hour = hour;
    this->minute = minute;
    strcpy_s((char*)dayTime.c_str(), dayTime.length()+1, dayTime.c_str());
}

Time::Time() : hour(0),
               minute(0),
               dayTime(NULL)
{
}

void Time::setTime()
{
    cout << "Enter the hour: ";
    cin  >> hour;
    cout << "Enter the minute: ";
    cin  >> minute;
    cout << "is it P.M. or A.M.? ";
    cin  >> dayTime;

    this->incrementMinutes();
}

int Time::incrementMinutes()
{
    if ( minute <= 0 )
    {
        minute %= 59;
    }
    else if ( minute >= 59 )
    {
        hour++; // we have a new hour
        minute %= 59; // get the rest of the minutes
        // it is unlikely that the user will enter a 4-5 digit amount.
    }
    this->incrementHours();
    return minute;
}

const int Time::incrementHours()
{
    if ( hour > 12 )
    {
        hour %= 12;
        this->incrementHours();
    }
    else if ( hour == 0 )
    {
        hour = 12;
    }
    return hour;
}


ostream& operator<<(ostream& out, const Time tObj)
{
    if ( tObj.getMinte() < 10 )
    {
            return out << endl << tObj.getHour() << ":"
                       << "0" << tObj.getMinte() << " "
                       << tObj.getDayTime()      << "\n"
               ;
    }
    else
    {
        return out << endl << tObj.getHour() << ":"
                       << tObj.getMinte()    << " "
                       << tObj.getDayTime()  << "\n"
               ;
    }
}

/*************************************/


Date::Date(string month, int day, int year) : month(month),
                                                    day(day),
                                                    year(year)
{
    strcpy_s((char*)month.c_str(), month.length()+1, month.c_str());
    this->day = day;
    this->year = year;
}

Date::Date() : month(0),
               day(0),
               year(0)
{

}

Date::~Date()
{
}

Date::Date(const Date &d) : month(d.month),
                            day(d.day),
                            year(d.year)
{

}

void Date::setDate()
{
    cout << "enter the month: ";
    cin  >> month;
    cout << "enter the numeric day: ";
    cin  >> day;
    cout << "enter the numeric year: ";
    cin  >> year;
    cout << endl;
}

ostream& operator<<(ostream& out, Date dObj)
{
    return out << endl << dObj.getMonth() << " "
                       << dObj.getDay()   << ", "
                       << dObj.getYear()  << "\n"
                ;
}

/*****************************************/

Event::Event(string eventName, const Date &myDate) : eventName(eventName),
                                                     userEvent(userEvent),
                                                     headByName(NULL)

{
    strcpy_s((char*)eventName.c_str(), eventName.length()+1, eventName.c_str());
}

Event::Event() : eventName(NULL), userEvent(NULL), headByName(NULL)
{
}

Event::~Event()
{
    node * temp_node = NULL;
    node * current_node = headByName;

    while ( current_node )
    {
        temp_node = current_node->nextByName;
        delete current_node;
        current_node = temp_node;
    }
}

void Event::insert(string eventName, const Date &myDate, const Time &myTime)
// when we insert we dont care about the time, just the name and the date
{
    node * current_node = new node();

    if ( headByName == NULL )
    {
        headByName = current_node;
        headByName->eventName = eventName;
    }
    else
    {
        node * search_node = headByName;
        node * prev_node   = NULL;

        while ( search_node != NULL )
        {
            prev_node = search_node;
            search_node = search_node->nextByName;
        }
        if ( NULL == prev_node )
        {
            headByName = current_node;
        }
        else
        {
            prev_node->nextByName    = current_node;
        }
            current_node->nextByName = search_node;
            current_node->eventName  = eventName  ;
    }
}

void Event::displayByName(ostream& out) const
{
    cout << "Scheduled Events are: " << endl << endl;
    node  * current_node = headByName;

    while ( current_node )
    {
        strcpy_s((char*)eventName.c_str(), current_node->eventName.length()+1, current_node->eventName.c_str());
        out << eventName.c_str() << endl;
        current_node = current_node->nextByName;
    }
}

Event::node::node() : nextByName(NULL), eventName(eventName)
{
    strcpy_s((char*)eventName.c_str(), eventName.length()+1, eventName.c_str());
}

void Event::setEvent()
{
    cout << "\n\nEnter a new event! ";
    cin.getline((char*)userEvent.c_str(), 256);

}

/*****************************/

int main()
{
    Date  dObj("March", 21, 2010); // instaintiate our Date class object by allocating default date paramateres.
    Event eObj("First Day of Spring", dObj);
    Time  tObj(10,12,"PM");

    cout << "default Time is: " << tObj << endl;
    cout << "default Date is: " << dObj << endl;

    eObj.insert("First Day of Spring", dObj, tObj);
    eObj.insert("Valentines Day",   Date("February",14,2010), tObj);
    eObj.insert("New Years Day",    Date("Janurary",1, 2011), tObj);
    eObj.insert("St. Patricks Day", Date("March",17, 2010),   tObj);

    eObj.displayByName(cout);

    eObj.setEvent();
    const char * const theEvent = eObj.getEvent().c_str();
    dObj.setDate();

    eObj.insert((string)theEvent, dObj, tObj);
    tObj.setTime();

    cout << "Your event: " << theEvent << " is scheduled for: " << endl
         << dObj << "at" << tObj;

    eObj.displayByName(cout);

    cin.ignore(2);
    return 0;
}

Ответы [ 4 ]

4 голосов
/ 24 марта 2010

Вы слишком полагаетесь на ручное управление памятью. Похоже, вы добавили объектно-ориентированный интерфейс в программу на C, а не использовали функции C ++. Попробуйте переключиться на хранение строк в std::string (я вижу, что вы уже используете одну), связанный список на std::list ( EDIT: на самом деле std::set будет лучше), и поместите объекты на стек, где это возможно. Вам вообще не нужны new или любые указатели в этой программе.

(Мой список предложений ниже предполагает, что каждый event имеет свой отдельный список; извините, если это не так.)

    class Time
    {
    private:

        string dayTime
            ;

        int hour,
            minute
            ;

    public:

        Time(int hour, int minute, string const dayTime); // constructor
        Time(const Time& myTime); // copy constructor

        Time(); // default constructor

        virtual ~Time(); // destructor

        void setTime();

        // using encapsulation
        const int getHour()  const  { return hour;   };
        const int getMinte() const  { return minute; };
        string const getDayTime() const  { return dayTime;  };

        const int incrementHours();   
        int incrementMinutes();

        friend ostream& operator<<(ostream& out, const Time * tPtr); // to write the objects attributes
    };

    class Date
    {

    private:
        string  month;
        int     day,
                year;

    public:

        Date(const char * month, int day, int year);
        Date(const Date& d);// copy constructor

        Date(); // default constructor
        virtual ~Date();

        void setDate();

        string const getMonth()  const { return month; };
        const int getDay()  const { return day;  };
        const int getYear() const { return year; };

        friend ostream& operator<<(ostream& out, const Date * dPtr); // to write the objects attributes
    };

    class Event
    {
    private:

        string eventName
            ;
        string userEvent;

        list< string > event_names;

    public:
        Event(const char * eventName, const Date &myDate);
        Event();

        virtual ~Event();   

        void insert(const char * eventName, const Date &myDate, const Time &myTime);
        void setEvent();

        string const getEvent() const { return userEvent; };
        void displayByName(ostream& out) const;

    };

… в основном…

        Date  dPtr("March", 21, 2010); // instaintiate our Date class object by allocating default date paramateres.
        Event ePtr("First Day of Spring", *dPtr);
        Time  tPtr(10,12,"PM");

Ваш код довольно многословен ...

1 голос
/ 24 марта 2010

Этот конструктор (при условии, что strcpy_s похож на стандартную функцию strcpy) недопустим.

Вы уже инициализировали minute, hour и day в списке инициализаторов, поэтому переназначение их в теле конструктора кажется ненужным.

c_str() возвращает доступную только для чтения (возможно, копию) контролируемой строки, поэтому попытка перезаписи ее потенциально опасна.

Я не вижу явных утечек памяти, но это может быть причиной некоторого неожиданного поведения.

    Time::Time(int hour, int minute, 
               string dayTime) : minute(minute),
                                 hour(hour),
                                 dayTime(dayTime)

    {
        this->hour = hour;
        this->minute = minute;
        strcpy_s((char*)dayTime.c_str(), dayTime.length()+1, dayTime.c_str());
    }
1 голос
/ 24 марта 2010

Вы не удаляете eventName в деструкторе событий.

Event::~Event()
{
delete [] eventName;

Кроме того,

 Time::~Time()
        {
            delete[] dayTime;
                   ^missing
        }

  Date::~Date()
        {
            delete[] month;
        }
0 голосов
/ 24 марта 2010

В вашем конструкторе Time вы инициализируете hour и minute дважды (просто неэффективно), но вы инициализируете dayTime с помощью strcpy. Вам нужно только это:

Time::Time(int hour, int minute, string dayTime):
  minute(minute), hour(hour), dayTime(dayTime)
{}

Также для конструктора по умолчанию вам нужно только это:

Time::Time(): hour(0), minute(0)
{}

, поскольку dayTime является строкой и будет инициализироваться для вас по умолчанию.

У вас похожие проблемы в конструкторах Date.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...