打印链表-访问冲突c++
Printing A linked List - Access Violation C++
我有一个链表,它接受几个输入文件,然后将它们放入链表中以便稍后打印它们。
我实现了一个打印函数,但它不能很好地工作,并给出访问冲突错误。我试着调试,不幸的是我找不到问题的根源。
函数中的错误行:
cout << ptr2->command + " ";
运行时错误:
第一次机会异常在0x00DAC616在file.exe: 0xC0000005:访问违反读取位置0xCDCDCDE1.
代码如下:
#include <iostream>
#include <fstream>
#include <string>
#include "strutils.h"
using namespace std;
struct Commands;
struct Functions
{
string fname;
Functions *right;
Commands *down;
};
struct Commands
{
string command;
Commands *next;
};
Functions *head;
Functions *temp;
Commands *temp2;
void StreamToLinkedList(ifstream &inputfile)
{
string s;
getline(inputfile, s);
temp = new Functions();
temp->fname = s.substr(0, s.length());
temp2 = temp->down;
while (!inputfile.eof())
{
getline(inputfile, s);
temp2 = new Commands();
temp2->command = s.substr(0, s.length()-1) + ",";
temp2 = temp2->next;
}
inputfile.clear();
inputfile.seekg(0);
}
void printLinkedList()
{
Functions *ptr = head;
Commands *ptr2;
while (ptr != nullptr)
{
cout << ptr->fname << endl;
ptr2 = ptr->down;
while (ptr2 != nullptr)
{
cout << ptr2->command + " ";
ptr2 = ptr2->next;
}
cout << endl;
ptr = ptr->right;
}
}
int main()
{
string file, key, s;
ifstream input;
cout <<"If you want to open a service (function) defining the file," << endl
<<"then press (Y/y) for 'yes', otherwise press any single key" << endl;
cin >> key;
ToLower(key);
if (key == "y")
{
cout << "Enter file the input file name: ";
cin >> file;
input.open(file.c_str());
if (input.fail())
{
cout << "Cannot open the file." << endl
<< "Program terminated." << endl;
cin.get();
cin.ignore();
return 0;
}
else
{
StreamToLinkedList(input);
head = temp;
temp = temp->right;
}
}
else
{
cout << "Cannot found any input file to process" <<endl
<< "Program terminated."<< endl;
cin.get();
cin.ignore();
return 0;
}
do
{
cout<< "Do you want to open another service defining file?"<<endl
<< "Press (Y/y) for 'yes', otherwise press any key" <<endl;
cin >> key;
ToLower(key);
if (key == "y")
{
cout << "Enter file the input file name: ";
cin >> file;
input.open(file.c_str());
if (input.fail())
{
cout << "Cannot open the file." << endl
<< "Program terminated." << endl;
cin.get();
cin.ignore();
return 0;
}
else
{
StreamToLinkedList(input);
temp = temp->right;
}
}
} while ( key == "y");
cout << "-------------------------------------------------------------------" << endl
<< "PRINTING AVAILABLE SERVICES (FUNCTIONS) TO BE CHOSEN FROM THE USERS" << endl
<< "-------------------------------------------------------------------" << endl << endl;
printLinkedList();
cin.get();
cin.ignore();
return 0;
}
错误代码是什么?
TO ANSWER
打印功能正常。您创建和管理列表的方式是错误的,可能是由于您从未初始化您的Functions.right
和Functions.down
字段,因此您的链表链接到无效内存。实际上,你并没有链接你的列表。
你的一些赋值,如temp2 = temp->down
和temp = temp->right
没有任何意义,因为这些字段没有初始化,因为你用新的对象覆盖了这些变量(temp
和temp2
)。
还有,你有重复的代码。您以完全相同的方式在两个不同的位置读取文件。问题是你的代码是错误的,所以你有双倍的错误要修复。这里代码重复的唯一明显原因是,您希望在用户第一次输入input和第n次输入input时显示不同的消息。
我建议将这段代码放在它自己的函数中。否则,找到一种更有效的方法来使用条件/循环,这样你就不会有那么多重复的代码。指出
我有"几件"事情要注意你的代码。LinkedList在两个名为Functions
和Commands
的类中实现。我知道你想有一个函数的列表,每个函数都有一个命令的列表,但是你必须学会把你的程序域和其他功能分开。
IE: LinkedList
是对象(任何类型)的容器。Function
和Command
是您为程序制作的特定内容,与链表本身无关。从概念的角度来看,Function
包含Command
s,但不一定要通过LinkedList
、map
或array
等。
你的代码需要一个概念分离,看看它会有多清晰
// Linked list of functions
Functions list;
// No need to comment this one
LinkedList functions;
(我们不讨论缺乏模板化类型)
此外,除非用复数来命名一个类有意义,否则你应该几乎总是使用单数(Functions
vs Function
)。这是因为当您实例化一个类时,您将拥有一个对象/实例,因此对类型使用复数形式可能会产生误导。考虑下面的声明,
Function someFunction; // This is a single function
Functions someFunction; // Is this one function or multiple functions??
List< Function > functions; // This is a list of functions
List< Functions > functions; // Is this a list of lists of functions???
你应该创建一个名为LinkedList的类(提示:如果可以的话使用模板使其更易于重用)。然后,如果您要从链表中分离函数和命令的实现,则可以制作如下内容:
template <class T>
struct LinkedList {
T* obj;
LinkedList<T>* next;
LinkedList() : obj( nullptr ), next( nullptr ) {}
};
struct Command {
string cname;
};
struct Function {
string fname;
LinkedList<Command> commands;
};
现在你要像这样声明函数列表,
LinkedList<Function> functions;
因为每个Function
都有自己的Command
列表,所以你有一个列表的列表,你不必像在当前实现中那样独立管理每个列表。当然,您的列表仍然需要接口(和内存管理),但这不在本问题的范围内。
当指针不指向任何对象时,将其初始化为nullptr。
temp = new Functions;
temp->right = nullptr;
temp->down = nullptr;
或者使用默认构造函数
struct Functions {
...
Functions() : right( nullptr ), down( nullptr ){}
};
然后初始化为
temp = new Functions();
访问冲突的问题是new默认情况下不会将其分配的内存归零,因此,最后一个结构体内部的指针指向一个随机值。
temp2 = new Commands; // this memory is not initilized to zero
temp2 = new Commands(); // this memory is initialized to zero, (all elements is set to 0)
- 写入位置0x0000000C时发生访问冲突
- 引发异常:读取访问冲突**dynamicArray**为0x1118235.发生
- 链表中写入访问冲突的未知原因
- C++中的openCV Mat访问冲突
- C++尝试深度复制唯一指针时出现内存访问冲突
- C++ 中动态二维数组的访问冲突
- 从嵌套循环中的 std::list 中删除将返回访问冲突
- 写入访问冲突异常
- 在类 12.exe 中0x7B37FF80 (ucrtbased.dll) 引发异常: 0xC0000005:访问冲突读
- 0xC0000005:访问冲突写入位置0xCDCDCDCD动态分配错误
- 读取访问冲突.这0xCDCDCDCD
- 0xC0000005:访问冲突读取位置 0x00000000. 重载 == 运算符的问题
- 插入数组时违反写访问冲突
- 使用 ReadProcessMemory 获取字符串值的访问冲突
- 尝试通过共享指针使用变量时读取访问冲突
- 堆栈上的 C++ 访问冲突写入异常
- 引发异常:写访问冲突. temp 为 nullptr
- 将静态字符数组中的字符分配给动态分配的字符数组 - 访问冲突
- 在C++中删除双向链表的头节点后出现访问冲突异常
- C++ 读取访问冲突,0xCDCDCDCD