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

时间:2018-03-24 10:06:12

标签: c++ c++11 debugging

在这里,我发现了一个关于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;
        }
    }
}

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

#include "dllist.h"

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

1 个答案:

答案 0 :(得分:3)

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