C++ 访问链表中的违规读取位置
C++ Access violation reading location in linked list
我最近一直在尝试解决这个reddit挑战(问题的第2部分(:
描述
感谢您为我提供的清单,我的想法更有条理! 我有几个问题,虽然我想你可以帮忙解决?>有时我会在列表项中输入错误的信息。也许为了防止这种情况,我可以修改/更新列表项?不过,这不是唯一的问题,当有 50+ 个项目时,我很难通过。您认为您可以添加对我的项目进行分类的功能吗?显然,如果我有这个,我也希望能够按类别查看! 哦,最后,你们中的一些人真的很棒,上次也这样做了,但是有没有办法以某种方式让我的列表保留状态,这样我就不必每次再次打开计算机时都重新键入它? 最新的待办事项列表应具有以下功能: 修改现有列表项 能够为列表项指定类别。列表项应该能够采用任意数量的类别 按类别查看 - 所有列表项都应能够按类别排序和输出,以便更轻松地浏览提交 保留状态 谢谢!
正式输入和输出
输出说明
创建的任何输出都应该是用户友好的。当我查看我的待办事项列表时,我应该能够轻松地将一个列表项与另一个列表项区分开来。 例子
(不要太从字面上理解,按照你想做的方式去做( 分类
输入:
类别输出
输入: 输出: ----编程---- - 像素不是像素不是像素 - 方案编程语言 - C语言内存 - 哈斯克尔音乐学院 - 一行代码的算法交响曲
----音乐---- - 民间音乐模式 - 旋律小调音阶的使用 - 哈斯克尔音乐学院 - 一行代码的算法交响曲
----音乐与编程---- - 哈斯克尔音乐学院 - 一行代码的算法交响曲
修改项目
我updateItem('Create Sine Waves in C', 'Create Sine Waves in Python'(; 该项目现在已从"在 C 中创建正弦波"更改为"在 Python 中创建正弦波"。这应该反映在您创建的 viewList 函数/方法中。
遇到的错误是我得到"访问违规读取位置"。这是因为在我的List<std::string>
中,我在调试该列表的任何节点data = <Error reading characters of string>
,但在退出ToDoList::addItem()
data = "Take a shower"
之前(或任何数据必须等于(之前意识到。
我希望我正确地解释了我的问题。
#include <iostream>
#include <string>
#include <vector>
template<class T>
struct Node
{
T data;
Node* next = nullptr;
Node();
Node(T item);
};
template<class T>
Node<T>::Node()
{ }
template<class T>
Node<T>::Node(T item) : data(item)
{ }
template<class T>
class List
{
Node<std::string>* head;
Node<std::string>* tail;
int size;
public:
List();
~List();
void addItem(T item);
void deleteItem(T item);
void display() const;
};
template<class T>
List<T>::List() : size(0)
{
head = new Node<std::string>();
tail = head;
}
template<class T>
List<T>::~List()
{
auto* temp = head;
for (int i = 0; i < size; ++i){
head = head->next;
delete temp;
temp = head;
}
}a
template<class T>
void List<T>::addItem(T item)
{
tail->data = item;
tail = tail->next = new Node<std::string>;
size++;
}
template<class T>
void List<T>::deleteItem(T item)
{
auto* temp = head;
for (int i = 0; i < size; ++i){
if (temp->data == item){
if (temp == head){
auto* h2 = head->next;
delete temp;
temp = 0;
head = h2;
}
else if (temp == tail){
delete temp;
temp = 0;
}
else{
temp->data = temp->next->data;
auto* te = temp->next->next;
delete temp->next;
temp->next = 0;
temp->next = te;
}
--size;
break;
}
temp = temp->next;
}
}
template <class T>
void List<T>::display() const
{
auto* temp = head;
for (int i = 0; i < size; ++i)
{
std::cout << "- " << temp->data;
temp = temp->next;
}
}
class Category
{
std::string name;
List<std::string> list;
public:
Category(std::string name);
void addItemToCategory(std::string item);
void doneItemInCategory(std::string item);
void displayCategory() const;
std::string getName() const;
};
Category::Category(std::string _name) : name(_name)
{ }
void Category::addItemToCategory(std::string item)
{
list.addItem(item);
}
void Category::doneItemInCategory(std::string item)
{
list.deleteItem(item);
}
void Category::displayCategory() const
{
list.display();
}
std::string Category::getName() const
{
return name;
}
class ToDoList
{
std::vector<Category> categories;
public:
ToDoList();
void addItem(std::string item, std::string category);
void viewList();
};
ToDoList::ToDoList()
{ }
void ToDoList::addItem(std::string item, std::string category)
{
if (!categories.size()){
Category newCategory(category);
newCategory.addItemToCategory(item);
categories.push_back(newCategory);
}
else{
for (auto& cate : categories){
if (cate.getName() == category){
cate.addItemToCategory(item);
return;
}
}
Category newCategory(category);
newCategory.addItemToCategory(item);
categories.push_back(newCategory);
}
}
void ToDoList::viewList()
{
for (const auto& cate : categories){
std::cout << "------" << cate.getName() << "------n";
cate.displayCategory();
}
std::cout << "n" <<std::endl ;
}
int main()
{
ToDoList list;
list.addItem("Take a shower", "x");
list.addItem("Go to work", "x");
list.viewList();
list.addItem("Buy a new phone", "y");
list.viewList();
std::cin.ignore(2);
}
我建议你阅读5法则。基本上,通过为List
定义析构函数但不声明任何复制/移动构造函数,您已经做到了这一点,因此对其进行任何类型的复制/移动都是危险的,并且会使您的List
处于不可用状态。具体来说,看看这个:
if (!categories.size()){
Category newCategory(category);
newCategory.addItemToCategory(item);
categories.push_back(newCategory);
}
这里发生了什么?你构造newCategory
,把它复制到categories
,然后摧毁它。由于您尚未定义任何复制构造函数,因此这是一个浅拷贝 - 它只是复制您的指针值,而不对它们指向的内存执行任何操作。当你摧毁它时会发生什么? ~Category()
运行,它调用 ~List()
,这会删除其所有Node
。现在你已经解除了该内存的分配,categories
中的东西指向垃圾。
若要解决此问题,可以为List
定义复制构造函数,这些构造函数分配新的Node
并复制所有数据。理想情况下,您还需要定义移动构造函数,这将允许您安全地执行此操作,而无需额外的内存分配。
- 0xC0000005:访问冲突读取位置 0x00000000. 重载 == 运算符的问题
- (此函数用于计算 SMA).在 FA.exe 中0x00509159引发异常: 0xC0000005:访问冲突读取位置0
- 0xC0000005:读取位置0xCDCDCDC1时发生访问冲突
- 0xC0000005:读取位置0xCDCDCDCD时发生访问冲突
- 0x0F50DF58:0xC0000005:访问冲突读取位置0x0047CA04时未处理的异常
- 在 DLL 中嵌入 Python:Py_DECREF列表对象时访问冲突读取位置
- 0xC0000005:访问冲突读取位置0x0000000000000008
- C++访问冲突读取位置0xDDDDDDCD当我尝试删除已更新的数组时
- 使用向量的函数崩溃,调试器说访问冲突读取位置
- OPENCV.3.0错误:0xc0000005:访问违规读取位置0x00000000
- 访问违规读取位置传递指针以在c中写入的DLL中起作用
- vc++ 访问冲突读取位置
- C++ - 智能指针 - 访问冲突读取位置0xDDDDDDDD
- C++访问冲突读取位置错误
- 访问违规读取位置和错误读取字符串的错误
- C 访问违规读取位置0xcccccccccccccccccccc和卡对象
- C++ 访问向量动态数组中的违规读取位置0xFFFFFFFFFFFFFFFF
- 0xC0000005:访问冲突读取位置0x0000000000000000.C++
- CUDA:访问违规读取位置
- OpenGL:glDrawArrays()引发异常(nvoglv32.dll)读取位置0x00000000时发生访问冲突