繁体   English   中英

C ++程序中的内存泄漏

[英]Memory leak in C++ program

谢谢大家,对于每一个const char *,我都将其替换为字符串。 再次感谢!

有人可以帮忙吗? :/( 这不是作业问题

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

您过于依赖手动内存管理。 看来您已经向C程序添加了一个面向对象的接口,而不是使用C ++的功能。 尝试切换到在std::string存储std::string (我看到您已经在使用一个std::string ),到std::list的链接std::list编辑:实际上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");

您的代码非常冗长...

您没有在事件析构函数中删除eventName

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

也,

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

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

此构造函数(假设strcpy_s与标准函数strcpy类似)是非法的。

您已经在初始化列表中初始化了minutehourday ,因此似乎不需要在构造函数主体中重新分配它们。

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

在您的Time构造函数中,您要初始化hourminute两次(效率低下),但是要用strcpy初始化dayTime 您只需要这样:

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

另外,对于默认构造函数,您仅需要以下内容:

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

因为dayTime是一个字符串,并且将默认为您初始化。

Date构造函数中,您有类似的问题。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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