简体   繁体   中英

Memory leak in C++ program

Thanks guys, for every const char * i went ahead and replaced it with string. THanks again!

Could someone help please? :/ ( This is not a homework question )

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

You're relying too much on manual memory management. It looks like you've added an object-oriented interface to a C program rather than using the features of C++. Try switching to storing strings in std::string (I see you're using one already), the linked list to std::list ( EDIT: actually std::set would be better), and putting objects on the stack where possible. You shouldn't need new or any pointers in this program at all.

(My list suggestion below assumes that each event has its own separate list; sorry if that's wrong.)

    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;

    };

… in main …

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

Your code is quite verbose…

You are not deleting eventName in Event destructor.

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

Also,

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

  Date::~Date()
        {
            delete[] month;
        }

This constructor (assuming that strcpy_s is something like the standard function strcpy ) is illegal.

You've already initialized minute , hour and day in the initializer list so reassigning them in the constructor body seems unnecessary.

c_str() returns a read-only (possibly copy) of the controlled string so trying to write over it is potentially dangerous.

I couldn't see any obvious memory leaks but this may be the cause of some unexpected behaviour.

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

In your Time constructor you are initialising hour and minute twice (just inefficient), but you are initialising dayTime with a strcpy. You only need this:

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

Also for the default constructor you only need this:

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

since dayTime is a string and will be default initialised for you.

You have similar problems in the Date constructors.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM