我得到一个断点,我不知道为啥

Posted

技术标签:

【中文标题】我得到一个断点,我不知道为啥【英文标题】:I am getting a breakpoint and i do not know why我得到一个断点,我不知道为什么 【发布时间】:2017-06-23 04:10:16 【问题描述】:

我正在尝试通过在 C++ 中使用链表来实现优先级队列。但是,当我运行程序时,它会在“priorityQLinkedList::dequeue()”方法中触发一个断点。有人能告诉我为什么会这样,并给我一些解决方法的建议吗?

代码:

#include <iostream>
#include <cstring>
#include <iomanip>

using namespace std; 

struct DAT

    int id;
    char fullname[50];
    double savings; 
;

struct NODE

    DAT data; 
    NODE *N; 
    NODE *P;
    NODE(const int i, const char *f, const double s)
    
        data.id = i;
        strcpy_s(data.fullname, f);
        data.savings = s;
        N = NULL; 
        P = NULL; 
    
;

class priorityQLinkedList

private:
    NODE *front; 
    NODE *back;
public:
    priorityQLinkedList()  front = NULL; back = NULL; 
    ~priorityQLinkedList()  destroyList(); 
    void enqueue(NODE *);
    NODE* dequeue();
    void destroyList(); 
;

void priorityQLinkedList::enqueue(NODE *n)

    if (front == NULL) 
        front = n;
        back = n;
    

    else 
        NODE *temp = front;
        if (n->data.id > temp->data.id)
        
            front->P = n;
            n->N = front; 
            front = n; 
        
        else
        
            //search for the posistion for the new node. 
            while (n->data.id < temp->data.id)
            
                if (temp->N == NULL) 
                    break; 
                
                temp = temp->N; 
            

            //New node id's smallest then all others
            if (temp->N == NULL && n->data.id < temp->data.id)
            
                back->N = n;
                n->P = back;
                back = n; 
            

            //New node id's is in the medium range.
            else 
                temp->P->N = n; 
                n->P = temp->P; 
                n->N = temp;
                temp->P = n; 
            
        
    


NODE* priorityQLinkedList::dequeue()

    NODE *temp; 

    //no nodes
    if (back == NULL) 
        return NULL; 
    

    //there is only one node
    else if (back->P == NULL) 
        NODE *temp2 = back; 
        temp = temp2;
        front = NULL;
        back = NULL; 
        delete temp2;
        return temp; 
    

    //there are more than one node
    else 
        NODE *temp2 = back;
        temp = temp2; 
        back = back->P;
        back->N = NULL;
        delete temp2;
        return temp;
    



void priorityQLinkedList::destroyList()

    while (front != NULL) 
        NODE *temp = front; 
        front = front->N;
        delete temp; 
    


void disp(NODE *m) 
    if (m == NULL) 
        cout << "\nQueue is Empty!!!" << endl; 
    
    else 
        cout << "\nID No.   : " << m->data.id; 
        cout << "\nFull Name    : " << m->data.fullname; 
        cout << "\nSalary   : " << setprecision(15) << m->data.savings << endl; 
    


int main() 
    priorityQLinkedList *Queue = new priorityQLinkedList();

    NODE No1(101, "Qasim Imtiaz", 567000.0000);
    NODE No2(102, "Hamad Ahmed", 360200.0000);
    NODE No3(103, "Fahad Ahmed", 726000.0000); 
    NODE No4(104, "Usmaan Arif", 689000.0000); 

    Queue->enqueue(&No4); 
    Queue->enqueue(&No3);
    Queue->enqueue(&No1);
    Queue->enqueue(&No2); 

    disp(Queue->dequeue());
    disp(Queue->dequeue());
    disp(Queue->dequeue());
    disp(Queue->dequeue()); 
    disp(Queue->dequeue());

    delete Queue; 
    return 0; 

【问题讨论】:

如果我弄错了,请纠正我,但是如果您 delete 将要出列的节点然后返回指向该节点的指针,这不会给调用者带来问题,然后调用者会得到返回一个“死”指针? @TimBiegeleisen 这就是正在发生的事情,你应该把它写成答案 @AndersK。我在下面尝试了一个答案。我没有看到处理这个问题的好方法,但我当然认为dequeue() 应该删除目标节点。我的回答是复制NODE 并返回给调用者。但随后调用者必须在某个时候调用delete 是的,这段代码的所有权很难看到。最好使用智能指针,然后函数可以返回一个共享指针。 【参考方案1】:

在您的dequeue() 方法中突出的一个问题是您在NODE 指针上调用delete,然后尝试将此已删除的指针返回给调用者。这可能会导致 dequeue() 本身出现错误,或者肯定会导致认为自己正在获取指向实际活动 NODE 对象的指针的调用者出现错误。

一个可能的解决方法是创建一个正在出队的NODE 的副本。你仍然会从你的列表中删除目标,但是调用者会返回一个有效的指针,他可以在以后释放它。

NODE* priorityQLinkedList::dequeue()

    NODE *temp; 

    // no nodes
    if (back == NULL) 
        return NULL; 
    

    NODE *temp2 = back; 
    temp = new NODE(temp2->data.id, temp2->data.fullname, temp2->data.savings);

    // there is only one node
    else if (back->P == NULL) 
        front = NULL;
        back = NULL; 
        delete temp2;
        return temp; 
    

    // there are more than one node
    else 
        back = back->P;
        back->N = NULL;
        delete temp2;
        return temp;
    

【讨论】:

您假设 priorityQLinkedList 拥有节点指针。它不是。它们被传递给enqueue,并归enqueue 的调用者所有。此解决方案不会解决 OP 的问题。 @1201ProgramAlarm 请编辑我的答案并修复它。我不是 C++ 大师,但返回已删除的指针对我来说有异味。希望我对 C++ 有更多了解。【参考方案2】:

您正在删除 dequeue 中不属于 priorityQLinkedList 的指针,因此您不知道删除它们是否安全。

在这种情况下,它们不是,因为传递给enqueue 的节点指针是本地的、基于堆栈的变量的地址,并且没有被new 分配。 (还有已经提到的删除指针然后返回它的问题,这是未定义的行为。)

对所示代码的修复是删除对dequeue 中的delete 的调用。但是,如果进行更改以便动态分配传递给 enqueue 的节点,则需要添加一些东西来处理。

【讨论】:

【参考方案3】:

1.首先将strcpy_s改为strcpy是struct NODE。

2. 使用 temp2--代替 Delete(temp2)。

//no nodes
if (back == NULL) 
    return NULL;


//there is only one node
else if (back->P == NULL) 
    NODE *temp2 = back;
    temp = temp2;
    front = NULL;
    back = NULL;
    temp2--;
    return temp;


//there are more than one node
else 
    NODE *temp2 = back;
    temp = temp2;
    back = back->P;
    back->N = NULL;
    temp2--;
    return temp;

我希望这能解决问题。

【讨论】:

以上是关于我得到一个断点,我不知道为啥的主要内容,如果未能解决你的问题,请参考以下文章

找不到父键,我不知道为啥

为啥我得到“类型测试的重复修饰符”以及如何修复它

未定义一个特定变量 我不知道为啥

存储过程不起作用,我不知道为啥

我收到“字符串下标超出范围错误”。我不知道为啥

我不知道为啥我不能在 C++ 中初始化一个数组的数组