简单地说,这个程序就是从字符串中创建一个字符链接列表。(从"HELLO"到head->h->e->l->l->o->NULL)每当我试图使用擦除功能删除磁头时,程序就会停止工作,给出"application.exe已停止工作…Windows正在检查解决方案…"。我想我的内存分配可能有问题,但我真的说不出来。非常感谢您的建议。
这适用于
void StringADT::append(string s)
{
for (int i = 0; i < s.length(); i++)
{
Node* NodePtr;
Node* newNode;
newNode = new Node;
newNode->data = s.at(i);
newNode->next = NULL;
if (!head)
{
head = newNode;
} else
{
NodePtr = head;
while (NodePtr->next)
{
NodePtr = NodePtr->next;
}
NodePtr->next = newNode;
}
}
}
void StringADT::erase(int pos) //pos = position to erase
{
if (!head || pos < 0 || pos > length() - 1)
return;
else {
Node* NodePtr;
NodePtr = head;
if (pos == 0)
{
NodePtr = head->next;
delete head; //PROBLEM COMES AFTER EXECUTION OF THIS LINE!!
}
}
}
这是我的
class StringADT{
private:
struct Node {
char data;
Node* next;
};
Node* head;
这是我的append函数,它可能是内存分配问题的根源。
void StringADT::append(string s) (appending string s to the linked list)
{
Node* NodePtr;
int slength = s.length();
Node *NodeArray;
NodeArray = new Node[slength];
if(!NodeArray)
return;
for (unsigned i = 0; i < s.length(); i++)
{
NodeArray[i].data = s.at(i);
NodeArray[i].next = NULL;
}
if (!head)
{
head = NodeArray;
NodePtr = head;
for(unsigned count = 1; count < slength; count ++)
{
NodePtr->next = (NodeArray + count);
NodePtr = NodePtr->next;
//cout << "number of count " << count << endl;
}
} else {
NodePtr = head;
while (NodePtr->next)
{
NodePtr = NodePtr->next;
}
for(unsigned count = 0; count < slength; count ++)
{
NodePtr->next = (NodeArray + count);
NodePtr = NodePtr->next;
//cout << "number of count " << count << endl;
}
}
}
擦除函数应该是这样的:
if (pos == 0)
{
NodePtr = head;
head = head->next;
delete NodePtr;
}
您按如下方式分配了Node对象:
NodeArray = new Node[slength];
在一个分配中有一个节点对象的数组。稍后,当您对该数组中的特定元素执行操作时,您将调用
delete head; //PROBLEM COMES AFTER EXECUTION OF THIS LINE!!
删除数组的特定元素。
这在C++内存分配中是不允许的。
如果已经分配了一个数组,则只能删除整个数组,而不能删除特定的元素。此外,您还需要使用arraydelete[]运算符,如下所示:
delete[] someArray;
但这涉及到你的设计的一个根本问题。您正在实现一个链表,但您正在分配一个数组。现在,理论上,你可以像以前那样分配一个链表元素数组,但这样做没有意义。数组是为特定数量的元素分配的;当你需要任意数量的元素,却不知道这个数字是什么时,通常会使用链表。
链表通常一次分配和删除一个元素,而不是放在预定义的数组中。获取新数据时,分配一个新节点,然后将其添加到列表中。
(上面的代码味道是,如果你有一个数组,为什么你需要链接元素?你可以迭代到下一个元素,而不是跟随指针。数组和链表不是组合使用的;它们有不同的用途。对于链表,你应该去掉数组并分配单个节点,然后也可以单独删除它们根本没有那个数组。)
-
很明显,问题是您分配了对象数组,而不想删除其中一个。您必须独立分配
Node
。也就是说,这是您需要修复的append
函数。 -
append应该写成
append(char)
,它只附加一个字符,而append(string const &)
(字符串复制成本可能很高,所以总是通过引用,通常是常量!)应该只在循环中调用它。和append(char const *)
,所以您也可以附加字符串文字! -
不要对没有随机访问权限的内容使用索引。为了让您不必考虑什么可以直接访问,只需学习更喜欢通过迭代器/指针进行迭代,而不是使用索引进行迭代!
我不举例子,因为对于任务,最好是你自己想出实际的代码,即使你必须反复要求澄清。