一个关于在函数中运行未调用语句的非常奇怪的错误

A very bizarre bug about run an uncalled statement in a function

本文关键字:语句 调用 非常 错误 运行 一个 函数      更新时间:2023-10-16

在这里,我发现了一个关于C++中一个小程序的非常奇怪的错误。

我写了一个双向链表,我认为这很简单,但它每次都崩溃,我不知道为什么。

经过长时间的调试,我发现它总是跳转到函数中的语句,然后崩溃。

我在dllist.cpp中标记了该声明.

这对我来说太奇怪了,你怎么能在函数中运行一个语句而不调用它?还是有其他问题?

dllist.h:

class DLLElement{
public:
DLLElement(void *itemPtr, int sortKey);
DLLElement *next;
DLLElement *prev;
int key;
void *item;
};
class DLList{
public:
DLList();
~DLList();

void *Remove(int *keyPtr);
bool isEmpty();
void SortedInsert(void *item, int sortKey);
private:
DLLElement *first;
DLLElement *last;
};

void genItems(DLList *dl, const int N);
void remove(DLList *dl, const int N);

dllist.cpp:

#include "dllist.h"
const int min = 0;
const int max = 1;
DLLElement::DLLElement(void *itemPtr, int sortKey){
item = itemPtr;
key = sortKey;
}
DLList::DLList() {
first = nullptr;
last = nullptr;
}
DLList::~DLList(){
int *key;
if(!isEmpty()){
Remove(key);
}
}
bool DLList::isEmpty() {
if(first == nullptr && last == nullptr)
return true;
else
return false;
}

void *DLList::Remove(int *keyPtr) {
if(isEmpty())       // if list is empty, then there is no need to search
return nullptr;
auto fst = first;
auto lst = last;
if(fst == lst){
first = nullptr;
last = nullptr;
*keyPtr = fst->key;
void *item = fst->item;
delete fst;
return item;
}
else{
first = first->next;
first->prev = nullptr;
///////// crush statement ///////////
*keyPtr = fst->key;
/////////////////////////////////////
void *item = fst->item;
delete fst;
return item;
}
}
void DLList::SortedInsert(void *item, int sortKey) {
DLLElement *newElm = new DLLElement(item, sortKey);
if(isEmpty()){
newElm->prev = nullptr;
newElm->next = nullptr;
first = newElm;
last = newElm;
return;
}
if(sortKey < (first->key)){     // if sortKey is even smaller than first key, then do preappend.
newElm->prev = nullptr;
newElm->next = first;
first->prev = newElm;
first = newElm;
return;
}
if(sortKey >= (last->key)){   // if sortKey is even larger than last key, then do append
newElm->next = nullptr;
newElm->prev = last;
last->next = newElm;
last = newElm;
return;
}
// else, assert newElm in the middle
auto fst = first;
auto lst = last;
while(fst!=lst){
fst = fst->next;
if(sortKey <= (fst->key)){
newElm->prev = fst->prev;
newElm->next = fst;
fst->prev->next = newElm;
fst->prev = newElm;
return;
}
}
}

在主函数中,只需调用它:

#include "dllist.h"
int main() {
DLList dl;
void* item = nullptr;
dl.SortedInsert(item, 5);
return 0;
}

DLList析构函数中,您将未初始化的指针int *key;传递给函数Remove当它被取消引用时会导致未定义的行为*keyPtr = fst->key;.