【问题标题】:System.AccessViolationException Attempted to read or write protected memorySystem.AccessViolationException 试图读取或写入受保护的内存
【发布时间】:2012-02-23 22:43:49
【问题描述】:

您好,我正在开发一个使用链表数组的程序,但运行它时遇到问题。我不断收到此错误,但找不到解决方法。我只会包含部分代码,这样一切都不会太混乱。错误消息是 NodeADT.h 中的第 112 行、MultiListADT.h 中的第 141 行和 main.cpp 中的第 21 行是引发错误的行。我将突出显示这些行以使其更容易。

Main.cpp

#include <iostream>
#include "MultiListADT.h"
#include <fstream>
#include <string>

using namespace std;

void main(void)
{
MultiListADT<string,100> myList;
string item;
ifstream data;
string input;
int x=0;

data.open("input.txt");

while (!data.eof())
{
    getline(data,input);
    myList.AddToFront(input);        //This is line 21
}

cout << myList << endl;

system("pause");
}

MultiListADT.h

#include <iostream>
#include <fstream>
#include "NodeADT.h"
#include <string>

using namespace std;

template <class TYPE,int threads>
class MultiListADT
{
public:
/** Constructor **/
MultiListADT();

/** Destructor **/
~MultiListADT();

/** Declare accessors (observers) **/
void ResetListForward(int=0);
void ResetListBackward(int=0);
bool IsEmpty(int=0);
int LengthIs(int=0);
bool Search(string, bool=true,int=0);
void GetNextItem(TYPE &,int i=0);
void GetPreviousItem(TYPE &,int=0);
int GetInfo(int=0);
friend ostream& operator << (ostream&, MultiListADT<TYPE, 100>&);

/** Declare mutators (transformers) **/
void MakeEmpty();
void AddToFront(TYPE);
void AddToRear(TYPE);
void InsertInOrder(TYPE);
void Delete(TYPE);
void Sort();

private:
NodeADT<TYPE,threads>* head[threads];
NodeADT<TYPE,threads>* tail[threads];
int length;
string indices[threads];
NodeADT<TYPE,threads>* currentNode[threads];
};

template <class TYPE,int threads>
MultiListADT<TYPE,threads>::MultiListADT()
{
head[threads] = new NodeADT<string,threads>(); 
tail[threads] = new NodeADT<string,threads>();
head[threads]->setNext(tail[threads]);
tail[threads]->setPrevious(head[threads]);
length = 0;
}

template <class TYPE,int threads>
void MultiListADT<TYPE,threads>::AddToFront(TYPE item)
{
head[0]->AddToFront(item);        //This is line 141

length++;
}

注意ADT.h

#include <iostream>
#include <fstream>
#include <string>

using namespace std;

const int null = 0;

template<class TYPE, int threads>
class MultiListADT;

template <class TYPE, int threads>
class NodeADT
{
public:
NodeADT();
NodeADT(TYPE);
~NodeADT();
TYPE getInfo();
NodeADT<TYPE, threads>* getPrevious(int=0);
NodeADT<TYPE, threads>* getNext(int=0);
void setNext(NodeADT<TYPE, threads>*,int=0);
void setPrevious(NodeADT<TYPE, threads>*,int=0);
bool Search(TYPE, bool=true,int=0);
void AddToFront(TYPE item);
void AddToRear(TYPE item);
void InsertInOrder(TYPE);
bool Delete(TYPE);
friend ostream& operator << (ostream&, MultiListADT<TYPE, threads>&);
private:
TYPE info;
NodeADT<TYPE, threads>* prev[threads];
NodeADT<TYPE, threads>* next[threads];
};

template <class TYPE,int threads>
NodeADT<TYPE,threads>::NodeADT()
{
prev[threads] = null;
next[threads] = null;
}

template <class TYPE,int threads>
NodeADT<TYPE,threads>::NodeADT(TYPE item)
{
info = item;
prev = null;
next = null;
}

template <class TYPE,int threads>
void NodeADT<TYPE,threads>::AddToFront(TYPE item)
{
NodeADT<TYPE,threads> *temp = new NodeADT<TYPE,threads>;
temp->info = item;  
temp->prev[0] = this;
temp->next[0] = next[0];
next[0]->prev[0] = temp;        //This is line 112
next[0] = temp;
}

【问题讨论】:

  • 与您的问题无关,但eof 不起作用(像那样)。
  • 您能否解释一下 eof 在这种情况下是如何不起作用的,因为它一直是为我设计的。
  • @Soul3lade: eof() 不会被设置,直到 getline 尝试在文件末尾读取。所以你所做的总是在最后读取一个空的 input 值。您可能应该这样做 while( getline( ...

标签: c++ data-structures linked-list


【解决方案1】:

认为这个错误意味着什么?

在第 112 行,next、prev 和 temp 的值从何而来,当它崩溃时它们设置为什么?知道值,你认为它为什么会崩溃?

同样在您的 NodeADT 构造函数之一中,您将 null 分配给数组的最后一个元素。或者看起来是这样。

问题:当您为 100 个元素的数组中编号为 100 的元素赋值时,当元素计数从 0 开始时会发生什么?

【讨论】:

  • 我猜我试图访问程序运行时无法访问的内存。 Temp->info 是发送的项目,而 Temp->prev 将是相同的地址,而 temp->next 设置为列表中的下一个地址。 prev 和 next 永远不会设置,因为那是程序崩溃的地方。对于您的问题,您将分配一个超出数组范围的值,这会导致错误。
  • @Soul3lade:这就是您认为地址设置的内容。然而,这种情况并非如此。一旦你发现那里发生了什么,你就会成为一个更好的程序员,所以我把它留给你去弄清楚。
  • 好吧,我完全理解我必须了解到底发生了什么,但请注意提供任何提示。
【解决方案2】:

我认为 Zan Lynx 暗示的答案是,您在 MultiListADT 的构造函数中使用 threads 作为数组的索引。在AddToFront 中,您使用 0 作为索引,但数组中的该元素从未被初始化。

【讨论】:

  • 好吧,我现在很困惑,我认为线程只是一个 int,允许我声明让我们说 next[] 的数组有多大。所以通过使用 next[0] 我只是使用数组的第一个列表。
  • 这一切都正确(线程是一个 int 并且 next[0] 是数组中的第一个元素),但是在您的构造函数中,您没有为 next[0] 赋值。您正在为 next[100] 分配一个值,该值超出了数组的范围,但看起来您可能希望将该值分配给 next[0]。我假设您稍后将添加更多代码来处理其他 99 个列表:)
  • 好吧,所以改变 next[threads] = null;到下一个[0] = null;
  • 嗯,有很多地方你正在使用 something [threads],它们可能都应该被改变。同样,我假设您有一些理由使用列表数组,因此您可能最终会使用 next[something] 而不是硬编码在运行时永远不会更改的单个索引。
  • 是的,数组的原因是 something[0] 将是读入的整个列表,而 something[1-99] 将是更多列表,它们将主列表的公共部分捆绑在一起所以说某事[1]将是包含“你好”等的字符串。但是我将构造函数改为让[线程]拥有[0],尽管我仍然收到相同的错误,所以要么我错过了一些东西,要么还有更多.
猜你喜欢
  • 2012-09-21
  • 1970-01-01
  • 1970-01-01
  • 2011-09-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-08
相关资源
最近更新 更多