链表中的内存泄漏

时间:2014-10-13 02:56:57

标签: c++ memory-leaks linked-list

我正在浏览链接列表并尝试删除已分配的内存,但我发现内存泄漏很多。我真的不确定为什么。相关代码:

Winery类的构造函数和析构函数:

Winery::Winery(const char * const name, const char * const location, const int acres, const int rating) :
name(new char[strlen(name) + 1]),
location(new char[strlen(location) + 1]),
acres(acres),
rating(rating)
{
    strcpy(this->name, name);
    strcpy(this->location, location);
}

Winery::~Winery()
{
    delete[] this->name;
    delete[] this->location;
    this->name = nullptr;
    this->location = nullptr;
}

我的List类的构造函数和析构函数:

List::List() :
headByName(nullptr),
headByRating(nullptr)
{

}

List::~List()
{
    Node    *frontNode(headByName);
    Node    *nextNode;

    while (frontNode) 
    {
        nextNode = frontNode->nextByName;
        delete frontNode;
        frontNode = nextNode;
    }
}

List类中包含的节点的构造函数:

List::Node::Node(const Winery& winery) :
item(winery.getName(), winery.getLocation(), winery.getAcres(), winery.getRating()),
nextByName(nullptr),
nextByRating(nullptr)
{

}

最后,我用一个函数将一个节点插入到链表中。这是我动态分配内存的唯一其他地方,所以它必须在某处,但我不知道它可能在哪里。

void List::insert(const Winery& winery)
{
    if (!headByName)
    {
        headByName = new Node(winery);
    }
    else
    {
        Node    *frontNode(headByName), *prevNode(headByName);
        Node    *newerNode = new Node(winery);

        frontNode = headByName;
        prevNode = frontNode;
        while (frontNode->nextByName)
        {
            if (strcmp(frontNode->item.getName(), winery.getName()) < 0)
            {
                frontNode->nextByName = prevNode->nextByName;
                prevNode->nextByName = newerNode;
            }
            else
            {
                prevNode = frontNode;
                frontNode = frontNode->nextByName;
            }
        }

        frontNode = headByName;
        prevNode = frontNode;
        while (frontNode->nextByName)
        {
            if (frontNode->item.getRating() < winery.getRating())
            {
                frontNode->nextByRating = prevNode->nextByRating;
                prevNode->nextByRating = newerNode;
            }
            else
            {
                prevNode = frontNode;
                frontNode = frontNode->nextByRating;
            }
        }
    }
}

我能想到的唯一一件事就是必须在某处制作一些副本并留在那里,但我不知道它可能在哪里。我的析构师看起来很好,所以我不知道在哪里可能会泄漏记忆。

编辑:我被要求完整地展示酒庄课程。这是头文件:

#include <ostream>

class Winery
{
public:

    Winery(const char * const name, const char * const location, const int acres, const int rating);
    virtual ~Winery(void);

    const char * const getName() const { return name; }
    const char * const getLocation() const { return location; }
    const int getAcres() const { return acres; }
    const int getRating() const { return rating; }

    static void displayColumnHeadings(std::ostream& out);

    friend std::ostream& operator<<(std::ostream& out, Winery *w);

private:
    char    *name;
    char    *location;
    int     acres;
    int     rating;
};
第二次编辑:我被要求发布主要功能。这是驱动程序文件:

#include "memoryleakdetect.h"       // this must be the first #include in each of your .cpp files
#include <iostream>
#include "winery.h"
#include "list.h"

using namespace std;

static List     *wineries;

// Ask list to insert a winery into the doubly-threaded linked list.
// Note what this function does with memory, which has implications for
// how you will (and will not) be able to use the winery instance that's
// passed to wineries->insert.
static void insertWinery(char *name, char *location, int acres, int rating)
{
    Winery  *w;
    char    *nm = new char[strlen(name) + 1];
    char    *loc = new char[strlen(location) + 1];

    strcpy(nm, name);
    strcpy(loc, location);
    w = new Winery(nm, loc, acres, rating);
    wineries->insert(*w);
    delete[] nm;
    delete[] loc;
    delete w;
}

// Display all wineries in the list,
// first in order by name, then in order by rating.
static void displayWineries(ostream& out)
{
    out << "+++ list by name" << endl;
    wineries->displayByName(out);
    out << endl << "+++ list by rating" << endl;
    wineries->displayByRating(out);
}

int main(int argc, char **argv)
{
    Winery  *wPtr;

    cout << "CS260 - Assignment 1 - " << Winery::YOUR_NAME << endl << endl;

    wineries = new List();

    insertWinery("Lopez Island Vineyard", "San Juan Islands", 7, 95);
    insertWinery("Gallo", "Napa Valley", 200, 25);
    insertWinery("Cooper Mountain", "Willamette Valley", 100, 47);
    insertWinery("Duck Pond Cellars", "Willamette Valley", 845, 70);
    insertWinery("Del Rio", "Bear Creek Valley", 200, 37);
    insertWinery("Weisinger's of Ashland", "Bear Creek Valley", 6, 83);
    insertWinery("LongSword", "Applegate Valley", 16, 85);

    displayWineries(cout);

    cout << endl << ">>> removing Cooper Mountain" << endl <<  endl;
    wineries->remove("Cooper Mountain");

    displayWineries(cout);

    cout << endl << ">>> inserting San Juan Vineyards" << endl << endl;
    insertWinery("San Juan Vineyards", "San Juan Islands", 20, 90);

    displayWineries(cout);

    cout << endl << ">>> search for \"Gallo\"" << endl << endl;
    wPtr = wineries->find("Gallo");
    if (wPtr != 0)
        cout << wPtr;
    else
        cout << "not found" << endl;

    cout << endl << ">>> search for \"No Such\"" << endl << endl;
    wPtr = wineries->find("No Such");
    if (wPtr != 0)
        cout << wPtr;
    else
        cout << "not found" << endl;

    cout << endl;

    delete wineries;

    // report on memory leaks in the Output Window
    #ifdef _DEBUG
    if (argc == 2) {
        _CrtSetReportMode( _CRT_WARN , _CRTDBG_MODE_FILE );
        _CrtSetReportFile( _CRT_WARN , _CRTDBG_FILE_STDERR );
        }
    _CrtDumpMemoryLeaks();
    #endif

    return 0;
}

0 个答案:

没有答案