0

我之前发布过并且在弄清楚如何深度复制我的双向链表方面得到了很好的帮助。我现在遇到了访问冲突“0xC000000005”的问题,我认为这是由尝试延迟空指针引起的。这是一项家庭作业,而且我是 C++ 新手,所以我只想得到一些帮助,找出我哪里出错了,而不是有人只给我工作代码。

这是我的教授给我的界面。我不能以任何方式修改它。

#ifndef TEXTANALYZER_H
#define TEXTANALYZER_H

#include <iostream>
#include <string>

using namespace std;

class TextAnalyzer {
private:

/*
* Class: Node
*
* This class represents a node in a sorted doubly linked list that stores a
* list of words and their frequency of occurrency.
*/
class Node {
public:
string word;
int wordFrequency;
Node* previous;
Node* next;

Node(const string& word,
     const int wordFrequency,
     Node* const previous,
     Node* const next)
: word(word),
      wordFrequency(wordFrequency),
      previous(previous),
      next(next)
    {}
}; // end ListNode
/*********************************************************************/

Node* head;
Node* tail;


/*
* Releases all the memory allocated to the list.
*/
void releaseNodes();

/*
* Makes a deep copy of the object.
*/
void copyNodes(Node* const copyHead);

/*
* Returns a populated Node.
* Throws a bad_alloc exception if memory is not allocated.
*/
Node* createNode(const string& word,
             const int wordFrequency,
             Node* const previous,
             Node* const next);

public:
/* 
* Initializes head and tail, each to a dymmy node.
*/
TextAnalyzer();

/*
* Makes a deep copy of the object passed in.
* Calls copyNodes() to do the actual work.     
*/
TextAnalyzer(const TextAnalyzer& copyObject);

/* 
* Releases all the memory allocated to the object.
* Calls the releaseNodes() method to do the actual work.
*/
~TextAnalyzer();

/* 
* Makes a deep copy of the rhs object.
*/
TextAnalyzer operator =(const TextAnalyzer& assignObject);

/*
* Inserts the word in a sorted order into the list. 
*
* If no Node exists with that initial character, one is added in
* sorted order. If one does exist (same word), then the word frequency
* of that word is incremented by one.
*/
void insertWord(const string& word);

/*
* Returns a count of all the words in the list.
*/
int wordCount() const;

/* 
* Returns a count of all the words with the initial character.
*/
int wordCountWithInitialCharacter(const char startsWith);

/*
* Returns a description of the object. The string is formatted as:
* [A words:]
*     [<word>(<count>)]
*     [<word>(<count>)]
*     ...
*
* [B words:]
*     [<word>(<count>)]
*     [<word>(<count>)]
*     ...
*
*...
*/
string toString() const;

};

#endif 

这是我的类定义:

#include "textAnalyzer.h"
#include <string>
#include <iostream>
#include <sstream>

TextAnalyzer::Node* TextAnalyzer::createNode(const string& word, const int wordFrequency, 
Node* const previous, Node* const next)
{
return new Node(word, wordFrequency, previous, next);
}
void TextAnalyzer::releaseNodes()
{
Node* del = tail;

while(tail != NULL)
{
    tail = tail->previous;
    tail->next = del;
    delete del;
    del = tail;
}

delete [] head;
delete [] tail;

head = tail = del = NULL;
}

void TextAnalyzer::copyNodes(Node* const copyHead)
{
head = new Node(*copyHead);
Node* iter = head->next;

for(Node* np = copyHead->next; np != NULL; np = np->next)
{
iter->next = new Node(*np);
iter = iter->next;
}

iter = NULL;
}

TextAnalyzer::TextAnalyzer():head(createNode("0",0,NULL,NULL)),tail(head)
{}

TextAnalyzer::TextAnalyzer(const TextAnalyzer& copyObject)
{
copyNodes(copyObject.head);
}

TextAnalyzer::~TextAnalyzer()
{
releaseNodes();
}

TextAnalyzer TextAnalyzer::operator=(const TextAnalyzer& assignObject)
{
return TextAnalyzer(assignObject);
}

void TextAnalyzer::insertWord(const string& word)
{
Node* iter = head->next;

while(iter != NULL)
{
if(iter->word == word)
    iter->wordFrequency++;
else if(iter->word[0] == word[0] && iter->next != NULL)
{
    Node* temp = iter->next;
    iter->next = createNode(word, 1, iter, temp);
    iter = iter->next;
    temp->previous = iter;

    temp = NULL;
}
else if(iter->word[0] == word[0] && iter->next == NULL)
{
    iter = createNode(word, 1, tail, NULL);
    tail = iter;
}
else
    iter = iter->next;
}

iter = NULL;
}

int TextAnalyzer::wordCount() const
{
Node* iter = head->next;
int count = 0;

while(iter != NULL)
count++;

return count;
}

int TextAnalyzer::wordCountWithInitialCharacter(const char startsWith)
{
Node* iter = head->next;
int count = 0;

for(int i = 0; i < wordCount(); i++)
{
if(startsWith == iter->word[0])
    count++;

iter->previous = iter;
iter = iter->next;
}

iter = NULL;

return count;
}

string TextAnalyzer::toString() const
{
Node* iter = head->next;
string desc = "List of words: \n";
ostringstream convert;

for(int i = 0; i < wordCount(); i++)
{
convert << iter->word[0] << " words:\n"
        << iter->word    << "(" 
        << iter->wordFrequency
        << ")\n";
iter->previous = iter;
iter = iter->next;
}

iter = NULL;

return desc + convert.str();
}

根据调试器,问题出现在我的 releaseNodes() 方法中。我已经添加了一条评论来指出它出现的特定行:

void TextAnalyzer::releaseNodes()
{
Node* del = tail;

while(tail != NULL)
{
    tail = tail->previous; //debugger flags this line when error occurs
    tail->next = del;
    delete del;
    del = tail;
}

delete [] head;
delete [] tail;

head = tail = del = NULL;
}

我不确定是什么导致了访问冲突,但就像我说的我是 C++ 新手。任何和所有的帮助表示赞赏。

4

3 回答 3

1

你不分配head and tailwith new [],所以你不删除它们delete []

delete [] head;
delete [] tail;

应该:

delete head;
delete tail;

混合new是未定义delete []行为。

于 2013-02-15T03:34:25.650 回答
0

除了比尔兹的回答之外,您的删除循环还有一些可疑之处。据我了解,您想将列表从前删除。是什么导致您进入现在的循环?似乎更自然的方法是:维护一个curr指针,从tail. 然后循环:递减curr,删除curr->nextcurr时停止head。然后删除head

于 2013-02-15T03:40:23.300 回答
0

在您的 copyNodes 中,您还需要设置前一个指针

于 2013-02-15T05:52:06.177 回答