有没有办法在销毁链表时取消引用 nullptr 时停止接收异常错误?
Posted
技术标签:
【中文标题】有没有办法在销毁链表时取消引用 nullptr 时停止接收异常错误?【英文标题】:Is there a way to stop receiving an exception error when dereferencing a nullptr while destroying a linked list? 【发布时间】:2021-02-12 16:32:46 【问题描述】:我需要销毁一个数组(通过散列填充和访问),其中多个指针指向 nullptr。我从教科书中复制了用于销毁链表的确切示例,但是当我尝试释放用于 Node 对象的内存时,仍然出现运行时异常。
我是否可以简单地告诉 Visual Studios 在执行期间忽略 nullptr 取消引用异常,或者是否有适当的方法来解除分配书中未显示的此类链表? enter image description here
#pragma once
#include <iostream>
#include <string>
#include <array>
#include <fstream>
class Manager
struct Node
int ID, type, capacity, DOB;
std::string Name;
Node* next = 0;
Node(int ID, int type, std::string Name, int DOB, int capacity) :
ID(ID),
type(type),
Name(Name),
DOB(DOB),
capacity(capacity)
;
std::array<Node*, 10> head;
public:
Manager();
int h(int);
void add(int, int, std::string, int, int);
void print(int);
void printAll();
void deleteOne(int);
~Manager();
;
#include "Manager.h"
Manager::Manager()
head.fill(0);
std::fstream records;
records.open("shipRecords.txt", std::ios::in);
if (records.is_open())
while (!records.eof())
int ID, type, DOB, capacity;
std::string Name;
records >> ID >> type >> Name >> capacity >> DOB;
add(ID, type, Name, capacity, DOB);
std::cout << "RECORDS INITIALIZED" << std::endl;
else
std::cout << "FILE NOT OPEN" << std::endl;
Manager::~Manager()
for (int i = 0; i < head.size(); i++)
Node* ptr = head[i];
Node* next = ptr;
while (ptr)
next = ptr->next;
delete ptr;
ptr = next->next;
在以下函数中取消引用 nullptrs 时,我没有遇到同样的问题。
void Manager::print(int ID)
Node* ptr = head[h(ID)];
if (ptr)
while (ptr->ID != ID && ptr)
ptr = ptr->next;
if (!ptr)
std::cout << "SHIP DOES NOT EXIST" << std::endl;
std::cout << ptr->ID
<< " " << ptr->type
<< " " << ptr->Name
<< " " << ptr->DOB
<< " " << ptr->capacity
<< std::endl;
else
std::cout << "SHIP DOES NOT EXIST" << std::endl;
void Manager::printAll()
int items = 0;
for (int i = 0; i < head.size(); i++)
Node* ptr = head[i];
while (ptr)
items++;
std::cout << ptr->ID
<< " " << ptr->type
<< " " << ptr->Name
<< " " << ptr->DOB
<< " " << ptr->capacity
<< std::endl;
ptr = ptr->next;
if (items == 0 && i == head.size() - 1)
std::cout << "NO SHIPS IN THE LIST" << std::endl;
【问题讨论】:
不要取消引用空指针。这不是销毁链表以取消引用任何内容的必要步骤。 Manager 是链表吗?我不得不问的事实指向糟糕的设计。您是要制作链表还是数组列表? 在print
函数中,在if (!ptr) std::cout << "SHIP DOES NOT EXIST" << std::endl;
之后应该退出函数。
@sweenish 对于赋值,我们应该创建一个指向节点(Ship 对象)的指针数组。我们使用散列函数 ID%10 填充这个数组。它应该教我们碰撞和链接。
那么听起来你根本不像在使用链表。
“多个指针指向 nullptr” - 我认为您的意思是“多个指针为空”。 (您写的内容意味着您有一个指向std::nullptr_t
的指针,如std::nullptr_t * ptr
,并且指向的东西 *ptr
是nullptr
。我写的内容将描述一个指针,例如Node* ptr
,它本身被分配了一个空指针值,例如nullptr
。)
【参考方案1】:
有没有办法在销毁链表时取消引用 nullptr 时停止接收异常错误?
不,取消引用 nullptr
会使您的程序具有未定义的行为。更正您的代码,使其永远不会尝试取消引用 nullptr
s。
【讨论】:
【参考方案2】:你的问题就在这里:
while (ptr)
next = ptr->next;
delete ptr;
ptr = next->next;
您的意思是,如果我知道ptr
是有效的,那么将它指向的任何内容作为其next
并将其存储在变量next
中(imo 不是一个好名字)。然后释放ptr
。最后,分配ptr
的next
指向的指针。
但是你不能保证next
是一个好的(非空)指针!
这看起来像是一个错字,应该是:
while (ptr)
next = ptr->next;
delete ptr;
ptr = next;
【讨论】:
【参考方案3】:这个方法看起来很可疑:
Manager::~Manager()
for (int i = 0; i < head.size(); i++)
Node* ptr = head[i];
Node* next = ptr;
while (ptr)
next = ptr->next;
delete ptr;
ptr = next->next;
您将 next
设置为 ptr->next
。没关系。您正在删除 ptr
,您已经对其进行了空检查。
但是你设置了ptr = next->next
。而且您真的只想将其设置为next
。我敢打赌这就是你的错误所在。
【讨论】:
以上是关于有没有办法在销毁链表时取消引用 nullptr 时停止接收异常错误?的主要内容,如果未能解决你的问题,请参考以下文章
Rails - 在before_destroy回调时取消销毁
C++/CLI 引用未在后续进入本地块时初始化为 nullptr
有没有办法访问/取消引用并查找存储在双指针向量中的元素的值? [关闭]