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