提问人:Horsio 提问时间:12/2/2022 最后编辑:mchHorsio 更新时间:12/2/2022 访问量:114
如何寻找悬空指针?
How to look for dangling pointers?
问:
我正在尝试在 C++ 中为链表构建一个类。我的教授说我的代码中有一个悬空的指针。我花了几个小时寻找它,但无论如何我都找不到它。我试着问一个朋友,他们也找不到。有没有办法在代码中查找悬空指针或识别它们?我会附上我的代码,以防万一它很明显,但老实说,我不知道这个悬空的指针在哪里。我知道这段代码不是最好的,但它已经通过了我和我教授的所有测试,除了有一个悬空的指针。我也听说过一种叫做智能指针的东西,但我认为我们不应该使用它,我不知道它们是什么。任何帮助找到此指针都是值得赞赏的。
#include "IntList.h"
#include <ostream>
using namespace std;
IntList::IntList() {
head = nullptr;
tail = nullptr;
}
IntList::IntList(const IntList &cpy) {
if(cpy.head == nullptr) {
head = nullptr;
tail = nullptr;
}
else {
IntNode *currNode = cpy.head;
IntNode *temp = cpy.head;
head = new IntNode(0);
head->value = temp->value;
currNode = head;
temp = temp->next;
while(temp != nullptr) {
currNode->next = new IntNode(0);
currNode = currNode->next;
currNode->value = temp->value;
currNode->next = nullptr;
temp = temp->next;
}
tail = currNode;
}
}
IntList::~IntList() {
clear();
}
void IntList::push_front(int value) {
IntNode *temp = new IntNode(value);
if(head == nullptr) {
head = temp;
tail = head;
}
else {
temp->next = head;
head = temp;
}
}
void IntList::pop_front() {
if(empty()) {
return;
}
else if(head->next == nullptr) {
delete head;
head = nullptr;
tail = nullptr;
}
else {
IntNode *temp = head;
head = head->next;
delete temp;
temp = nullptr;
}
}
void IntList::push_back(int value) {
IntNode *temp = new IntNode(value);
if(tail != nullptr) {
tail->next = temp;
}
tail = temp;
if(head == nullptr) {
head = tail;
}
}
bool IntList::empty() const {
if(head == nullptr) {
return true;
}
return false;
}
const int & IntList::front() const {
return head->value;
}
const int & IntList::back() const {
return tail->value;
}
void IntList::clear() {
IntNode *currNode = head;
IntNode *temp = currNode;
// unsigned i = 1;
while(currNode != nullptr) {
currNode = currNode->next;
temp->next = nullptr;
delete temp;
temp = currNode;
// cout << "deleted node " << i << endl;
// i++;
}
head = nullptr;
tail = nullptr;
}
void IntList::selection_sort() {
IntNode *loc = nullptr;
IntNode *temp = new IntNode(0);
IntNode *currNode = nullptr;
IntNode *swap = nullptr;
int min = 0;
if(head == nullptr) {
return;
}
else if(head->next == nullptr) {
return;
}
else {
for(currNode = head; currNode != nullptr; currNode = currNode->next) {
loc = currNode;
min = currNode->value;
for(swap = currNode; swap != nullptr; swap = swap->next) {
if(swap->value < min) {
min = swap->value;
loc = swap;
}
}
temp->value = currNode->value;
currNode->value = loc->value;
loc->value = temp->value;
}
}
delete temp;
temp = nullptr;
}
void IntList::insert_ordered(int value) {
if(head == nullptr || head->value >= value) {
push_front(value);
}
else if(tail->value <= value) {
push_back(value);
}
else {
IntNode *newNode = new IntNode(value);
for(IntNode *currNode = head; currNode != tail; currNode = currNode->next) {
if(currNode->next->value > newNode->value) {
newNode->next = currNode->next;
currNode->next = newNode;
break;
}
}
}
}
void IntList::remove_duplicates() {
if(head == nullptr) {
return;
}
else if(head->next == nullptr) {
return;
}
else {
IntNode *temp = head;
for(IntNode *currNode = head; currNode != nullptr; currNode = currNode->next) {
temp = currNode;
for(IntNode *check = currNode->next; check != nullptr; check = check->next) {
if(check->value == currNode->value) {
temp->next = check->next;
if(check == tail) {
tail = temp;
}
if(check->next != nullptr) {
check->next = nullptr;
}
delete check;
check = temp;
}
temp = check;
}
}
}
}
IntList & IntList::operator=(const IntList &rhs) {
IntList *newList = new IntList(rhs);
swap(newList->head, head);
newList->clear();
delete newList;
return *this;
}
ostream & operator<<(ostream &out, const IntList &rhs) {
IntNode *currNode = rhs.head;
while(currNode != nullptr) {
out << currNode->value;
currNode = currNode->next;
if(currNode != nullptr) {
out << " ";
}
}
return out;
}
IntNode * IntList::min(IntNode *min) {
return nullptr;
}
void IntList::copy(const IntList &) {}
我尝试在适当的时候删除内存,我通常会在确保它们没有悬空之后将指针分配给 nullptr。我真的不知道我做错了什么,它通过了测试,但显然在长时间使用后,它会导致不确定的行为。
答:
1赞
john
12/2/2022
#1
被窃听了。这是一个显示错误的测试operator=
int main()
{
IntList x;
x.push_back(1);
x.push_back(2);
IntList y;
y.push_back(3);
y.push_back(4);
x = y;
cout << x.back() << '\n';
}
这输出(对我来说)而不是预期的.该 bug 的原因是无法更新成员变量。我想你可以称之为悬空指针。-572662307
4
operator=
tail
如果你有一个复制构造函数和一个交换成员函数,那么简单可靠的实现方法是使用复制和交换习惯用语。看起来你正在尝试,但如果是这样,那么你就犯了错误。operator=
要回答所提出的问题,不,没有万无一失的方法来识别悬空指针。首先尽量不要使用它们(即指针)是最好的建议。但是,当你学习时,你显然必须经历痛苦。
评论
-fsanitize=address -g
operator=
tail