我编写了一个简单的控制台程序,用于测试我正在构建的库中的一些关键类。现在,代码可以正确构建,没有错误。但是,在执行完代码后,我发现应用程序在代码中的某个点调用 Index 方法后停止工作。我尝试调试几种不同的方法来获取有关该问题的更多信息,但我收集的信息对我没有任何帮助。也许它会帮助其他知道我没有做什么(或做错了)的人。
这是 Util 命名空间的内容;
template<typename var>
class VectorNode
{
public:
VectorNode(var value, VectorNode<var>* next = NULL, VectorNode<var>* prev = NULL)
{
data = value;
t_next = next;
t_prev = prev;
}
~VectorNode()
{
if (t_next != NULL)
delete t_next;
}
virtual VectorNode<var>* Next(){ return t_next; } // get the next node in line
virtual void Next(VectorNode<var>* newNode){ t_next = newNode; } // set the next node in line
virtual VectorNode<var>* Prev(){ return t_prev; }// get the previous node in line
virtual void Prev(VectorNode<var>* newNode){ t_prev = newNode; } // set the previous node in line
virtual var Value(){ return data; } // get the node's value
private:
var data;
VectorNode<var>* t_next;
VectorNode<var>* t_prev;
};
template<typename var>
class Vector
{
public:
Vector()
{
tailNode = new VectorNode<var>(*(new var));
headNode = new VectorNode<var>(*(new var), tailNode);
tailNode->Prev(headNode);
size = new int;
*size = 0;
}
~Vector()
{
delete headNode;
delete size;
}
int Size(){ return *size; } // get the size of a vector
void Add(var toAdd, int index = 0) //
{
VectorNode<var>* lastNode;
if (index > (*size))
index = *size;
if (index < 1) // add to the end of the vector
{
lastNode = tailNode;
}
else
{
int i;
if (index <= (*size / 2)) // if the index is less than half the size, iterate forwards
{
lastNode = headNode;
for (i = 1; i <= index; i++){ lastNode = lastNode->Next(); }
}
else // otherwise, iterate backwards
{
lastNode = tailNode;
for (i = *size; i >= index; i--){ lastNode = lastNode->Prev(); }
}
}
VectorNode<var>* temp = lastNode->Prev();
VectorNode<var>* newNode = new VectorNode<var>(toAdd, lastNode, temp);
lastNode->Prev(newNode);
temp->Next(newNode);
*size = *size + 1;
}
void Remove(int index) // remove an index
{
VectorNode<var>* toRemove;
VectorNode<var>* lastNode;
int i;
if ((index > *size) || (index < 1)) // if not in the domain...
index = *size;
if (index <= (*size / 2)) // iterate forwards
{
lastNode = headNode;
for (i = 1; i < index+2; i++){ lastNode = lastNode->Next(); }
}
else // iterate backwards
{
lastNode = tailNode;
for (i = *size; i > index; i--){ lastNode = lastNode->Prev(); }
}
toRemove = lastNode->Prev();
VectorNode<var>* temp = toRemove->Prev();
temp->Next(lastNode);
lastNode->Prev(temp);
delete toRemove;
*size = *size - 1;
}
var Index(int index) // get the value of a node
{
VectorNode<var>* lastNode;
int i;
if (index <= (*size / 2)) // iterate forwards
{
lastNode = headNode;
for (i = 1; i <= index; i++){ lastNode = lastNode->Next(); }
}
else // iterate backwards
{
lastNode = tailNode;
for (i = *size; i >= index; i--){ lastNode = lastNode->Prev();}
}
return lastNode->Value();
}
private:
int* size;
VectorNode<var>* tailNode; // the head and tail nodes are placeholders, to keep the list inside its boundaries
VectorNode<var>* headNode;
};
如果您不想阅读那篇文章,我会在每种方法中添加注释,解释其总体用途。此外,我尝试添加一些我的一些代码块的小解释。
而且,这是入口函数和包含项;
#include "iostream"
#include "stdlib.h" // this has nothing in it that's being used
#include "testhead.h" // the location of the Util namespace
int main()
{
using namespace Util;
Vector<int>* x = new Vector<int>();
x->Add(42);
x->Add(24);
x->Add(12);
x->Add(21);
std::cout << "Listing Indices\n";
for (int i = 1; i <= x->Size(); i++)
{
std::cout << i << "\t" << x->Index(i) << "\n";
}
std::cout << "Size(pre-removal):\t" << x->Size() << "\n";
x->Remove(2);
std::cout << "Size(post-removal):\t" << x->Size() << "\n";
std::cout << "Listing Indices\n";
std::cout << 3 << "\t" << x->Index(3) << "\n";
for (int i = 1; i <= x->Size(); i++)
{
std::cout << i << "\t" << x->Index(i) << "\n";
}
system("Pause");
}
好的,我得到的结果是这个。在使用 Remove 方法之前,可以从 Vector 类中自由访问任何索引。但是,使用remove方法后,无论删除什么索引,都无法访问大于1的索引。除了,在我们删除第一个索引的情况下,没有索引可以被访问。我尝试单步执行代码,但它让我想到了 index 方法中的这行代码;
else
{
lastNode = tailNode;
for (i = *size; i >= index; i--){ lastNode = lastNode->Prev();} // error occurs after running this line
}
现在,由于我能够找出导致问题的 Remove 方法,因此我返回并获得了一些关于该问题的输出。在完成执行之前,我让它运行以下行,两次。在 toRemove 被删除之前一次,在它被删除之后再一次。
std::cout << (lastNode->Prev() == temp) << "\t" << (temp->Next() == lastNode) << "\n";
在它被删除之前,它会打印两次 1,表示比较为真。但是,我第二次调用 Prev 和 Next 方法时,程序就会冻结。我知道这是因为我释放了内存中的位置,但比较显示从其他节点到我删除的节点的任何引用都消失了。现在,我的具体问题是为什么会导致这种情况,我该如何解决?我对管理堆上的内存有一点了解,但这似乎并不完全会导致程序出现任何问题。因此,如果有人愿意提供它,我可以使用一个简短的解释来解释为什么会发生这种情况。
如果有任何帮助,我正在使用 Code::Blocks IDE 和 GNU GCC 编译器。另外,如果我做错了与我问问题的方式有关的事情,请告诉我。我不经常访问 Stack Overflow,也不会在这里提问。据我所知,这只是回答您的问题的最佳场所。