构建代码时,在输出窗口中没有任何错误。但是,在运行它之后,编译器在我的代码中抛出一个异常(我将在抛出该异常的位置进行注释),并说“抛出异常:读取访问冲突。 temp为0xCDCDCDCD。”。
我尝试研究此错误是什么,但我发现这是针对未分配的内存的,但是我看不到未分配的位置。
这是我的链接列表.cpp文件。在此文件末尾的一行中引发了异常。
#include "linkedlist.h"
struct ll::node
{
weapons data;
node* next;
};
ll::ll()
{
head = NULL;
}
ll::~ll()
{
while (head != NULL)
{
node* temp = head;
head = head->next;
delete temp;
}
}
void ll::addItem(weapons obj)
{
node* newNode = new node;
node* temp = head;
newNode->data = obj;
if (head == NULL)
head = newNode;
return;
while (temp->next != NULL)
{
temp = temp->next;
}
if (temp->next == NULL)
{
temp->next = newNode;
return;
}
}
void ll::displayItems()
{
for (node* temp = head; temp != NULL; temp = temp->next)
{
temp->data.getDescription(); //EXCEPTION THROWN HERE
}
}
此文件具有继承的类“武器”,该类被称为“临时->数据”。以及我有“ getDescription”的地方。
#include <vector>
using namespace std;
//base class
class inventory
{
protected:
//number of items in inventory
int mNumItems;
public:
//getters
void displayInv();
int getNumItems();
virtual void getDescription();
};
//weapon class
class weapons : public inventory
{
private:
//name of object
string mName;
//what the object is
string mInfo;
//how much of the object
int mAmount;
//how much damage does it do
double mDamage;
public:
//constructor
weapons();
weapons(string, string, double, int);
//getters
string getName();
void getDescription();
int getAmount();
double getDamage();
string getInfo();
//mutators
void setAmount(int);
};
这是我定义武器的地方
//weapon class
weapons::weapons()
{
mName = " ";
mInfo = " ";
mDamage = 0.0;
mAmount = 0;
}
weapons::weapons(string name, string info, double dmg, int amt)
{
mName = name;
mInfo = info;
mDamage = dmg;
mAmount = amt;
}
string weapons::getName()
{
return mName;
}
int weapons::getAmount()
{
return mAmount;
}
double weapons::getDamage()
{
return mDamage;
}
string weapons::getInfo()
{
return mInfo;
}
void weapons::getDescription()
{
cout << getName() << ", " << getDamage() << " damage, " << getInfo() << " Amount: " << getAmount() << endl;
}
void weapons::setAmount(int amt)
{
mAmount = amt;
}
让我知道是否需要添加其他文件!
我得到了预期的结果,因为它可以描述我在链接列表中拥有的项目。不幸的是,我唯一的问题是引发了该异常。
答案 0 :(得分:2)
在
struct ll::node
{
weapons data;
node* next;
};
和
void ll::addItem(weapons obj)
{
node* newNode = new node; // leaks if node not added
node* temp = head;
newNode->data = obj;
if (head == NULL)
head = newNode;
return; // this is a NASTY bug of a different sort. Most of the time
// the function will exit without doing ANYTHING
while (temp->next != NULL)
{
temp = temp->next;
}
if (temp->next == NULL) // the only way out of the above loop is if
// temp->next == NULL. This if is redundant.
{
temp->next = newNode;
return;
}
}
没有任何事情将newNode->next
设置为安全值。允许
while (temp->next != NULL)
{
temp = temp->next;
}
之所以失败,是因为无法保证temp->next
永远是NULL
,并且循环从列表的末尾开始。
强制next
达到安全值。
struct ll::node
{
weapons data;
node* next = NULL;
};
或更通用的版本
struct ll::node
{
weapons data;
node* next;
node(const weapons & weap, // const reference eliminates a possible copy
node * link = NULL): // if you know what the next link will be,
// you can add it here. If not, it's always NULL
data(weap),
next(link)
{
}
};
addItem
现在看起来像
void ll::addItem(const weapons & obj)
{
if (head == NULL)
{
head = new node(obj); // only making node if we need it
// less chance of leak
}
else
{
node * temp = head;
while (temp->next != NULL)
{
temp = temp->next;
}
temp->next = newNode(obj);
}
}
但是您可以在这里做一些非常偷偷摸摸的事情,以使生活更轻松。 head
实际上是另一个名称的next
指针,因此,如果您可以抽象化另一个名称...而且我们可以通过跟踪指向next
的指针而不是指向{{ 1}}。当您必须插入或删除项目时,这确实非常方便:您既可以参考所讨论的节点,也可以参考先前节点中的插入点。
node
一半的代码。如何帮助删除的示例:
void ll::addItem(const weapons & obj)
{
node ** temp = &head; // get pointer to insertion point
while ((*temp) != NULL) // next node, including head, is not null
{
temp = &(*temp)->next; // get pointer to next insertion point
}
*temp = newNode(obj); // insert node
}