使用等于运算符时遇到问题。以退出代码 11 结束 [关闭]

Posted

技术标签:

【中文标题】使用等于运算符时遇到问题。以退出代码 11 结束 [关闭]【英文标题】:Having trouble with equals operator. Finishing with exit code 11 [closed] 【发布时间】:2021-03-08 21:45:44 【问题描述】:

谁能帮我弄清楚我的 =operator 出了什么问题?如果没有这两个函数,我的程序可以完美运行,但是一旦实现它们就会导致错误以退出代码 11 结束。

我正在尝试将两个链表设置为彼此相等。

virticalList::virticalList(const virticalList &p2) 
    *this=p2;


virticalList & virticalList::operator=(const virticalList& p2)

    Node* temp = p2.head->getNext();
    head = new Node(p2.head->getValue(),0);
    Node* curr = head;
    while(temp!=NULL)
        curr->setNext(new Node());
        curr->getNext()->setValue(temp->getValue());
        temp = temp->getNext();
    
    return *this;

我认为问题出在我的 operator = 函数中。或者在私有成员头中。

这是我完整的 virticalList 类:

class virticalList

private:
    Node* head = new Node();
public:
    virticalList();
    void print();
    void virtInc();
    ~virticalList();
    virticalList(const virticalList &p2);
    virticalList& operator=(const virticalList& p2);
;

virticalList::virticalList()

    head -> setValue(10);

    Node * ptr = head;
    for(int i = 10; i<20; i++)
    
        ptr -> setNext(new Node());
        ptr -> getNext()->setValue(i);
        ptr -> getNext()->setNext(nullptr);
        ptr = ptr -> getNext();
    


virticalList::~virticalList() 
    Node * des = head;
    Node * d = des->getNext();
    while(des -> getNext()->getValue()!=NULL)
        delete des;
        des = d;
        if(d->getNext()!= nullptr)
            d = d->getNext();
        
    


void virticalList::print()

     Node * print = head;
    while(print -> getNext()->getValue()!=NULL)
         cout << print -> getValue() << " ";
         print = print -> getNext();
     
     cout << "\n";


void virticalList::virtInc()

    Node * inc = head;
    while(inc -> getNext()->getValue()!=NULL)
        inc -> setValue(inc -> getValue()+1);
        inc = inc -> getNext();
    


virticalList::virticalList(const virticalList &p2) 
    *this=p2;


virticalList & virticalList::operator=(const virticalList& p2)

    Node* temp = p2.head->getNext();
    head = new Node(p2.head->getValue(),0);
    Node* curr = head;
    while(temp!=NULL)
        curr->setNext(new Node());
        curr->getNext()->setValue(temp->getValue());
        temp = temp->getNext();
    
    return *this;

这也是我的节点类供参考:

class Node
        
        private:
            int value;
            Node* next;
        public:
            Node();
            Node(int v, Node * next);
            void setValue(int v);
            int getValue();
            Node* getNext();
            void setNext(Node* theNewNext);
        ;

Node::Node()

    next = 0;
    value = 0;

Node::Node(int v, Node * next_in)

    value = v;next = next_in;

void Node::setValue(int v)

    value = v;

int Node::getValue()

    return value;

Node* Node::getNext()

    return next;

void Node::setNext(Node* theNewNext)

    next = theNewNext;

【问题讨论】:

如果您认为自己知道错误原因,您是否尝试过使用minimal reproducible example?退出代码11也是你得到的错误吗?因为在这里看到:Why should I post complete errors? Why isn't the message itself enough? 一个完整的错误信息更好 代码中仍然存在内存泄漏,就像今天早些时候一样。但是,这不应该导致它崩溃。 @TheGrandJ 是的,我得到的唯一错误是退出代码 11 operator= 设置了一个恰好有 2 个节点的列表(并在此过程中泄漏了一堆节点),无论 p2 中有多少节点。然而,各种成员函数,例如print(),期望列表至少包含 10 个节点;否则他们会直接通过一个空指针。 该代码中有许多可能的错误原因。几个函数多次调用getNext(),而不检查它是否返回了null——之后每次调用都有未定义的行为。复制构造函数(用于初始化对象,其生命周期在构造函数完成后开始)调用该类的 operator=() 函数(假定 *this 是先前构造的对象)也是相当不寻常的做法。更常用的方法(例如复制和交换习语)是让赋值运算符使用复制构造函数。 【参考方案1】:

显示的代码有很多错误。我看到内存泄漏。我看到循环没有正确迭代节点,最终将取消引用nullptrs。我看到复制构造函数被实现为调用operator=,而不是相反。

我建议重写整个内容,例如:

class Node

private:
    int value = 0;
    Node* next = nullptr;

public:
    Node(int v = 0, Node* n = nullptr);
    int getValue() const;
    void setValue(int v);
    Node* getNext() const;
    void setNext(Node* n);
;

Node::Node(int v, Node* n) :
    value(v),
    next(n)



int Node::getValue() const

    return value;


void Node::setValue(int v)

    value = v;


Node* Node::getNext() const

    return next;


void Node::setNext(Node* n)

    next = n;

class virticalList

private:
    Node* head = nullptr;

public:
    virticalList();
    virticalList(const virticalList &p2);
    ~virticalList();

    virticalList& operator=(const virticalList& p2);

    void print() const;
    void virtInc();
;
virticalList::virticalList() :
    head(new Node(10))

    Node* ptr = head;
    for(int i = 11; i < 20; ++i)
    
        ptr->setNext(new Node(i));
        ptr = ptr->getNext();
    


virticalList::virticalList(const virticalList &p2) 
    if (p2.head) 
        Node* temp = p2.head;
        Node* curr = head = new Node(temp->getValue());
        while (temp = temp->getNext()) 
            curr->setNext(new Node(temp->getValue()));
            curr = curr->getNext();
        
    


virticalList::~virticalList() 
    Node* ptr = head, *next;
    while (ptr) 
        next = ptr->getNext();
        delete ptr;
        ptr = next;
    


virticalList& virticalList::operator=(const virticalList& p2)

    if (this != &p2) 
        virticalList temp(p2);
        //std::swap(head, temp.head);
        Node* ptr = head;
        head = temp.head;
        temp.head = ptr;
    
    return *this;


void virticalList::print() const

    Node* ptr = head;
    while (ptr) 
        cout << ptr->getValue() << " ";
        ptr = ptr->getNext();
    
    cout << "\n";


void virticalList::virtInc()

    Node* ptr = head;
    while (ptr) 
        ptr->setValue(ptr->getValue()+1);
        ptr = ptr->getNext();
    

Live Demo

如果您将virticalList 设为Nodefriend,那么virticalList 可以直接访问Node::next 成员,您可以稍微简化virticalList 构造函数:

class Node

private:
    int value = 0;
    Node* next = nullptr;

public:
    Node(int v = 0, Node* n = nullptr);
    int getValue() const;
    void setValue(int v);
    Node* getNext() const;
    void setNext(Node* n);

    friend class virticalList;
;

Node::Node(int v, Node* n) :
    value(v),
    next(n)



int Node::getValue() const

    return value;


void Node::setValue(int v)

    value = v;


Node* Node::getNext() const

    return next;


void Node::setNext(Node* n)

    next = n;

class virticalList

private:
    Node* head = nullptr;

public:
    virticalList();
    virticalList(const virticalList &p2);
    ~virticalList();

    virticalList& operator=(const virticalList& p2);

    void print() const;
    void virtInc();
;
virticalList::virticalList()

    Node** ptr = &head;
    for(int i = 10; i < 20; ++i)
    
        *ptr = new Node(i);
        ptr = &((*ptr)->next);
    


virticalList::virticalList(const virticalList &p2) 
    Node** curr = &head;
    Node* temp = p2.head;
    while (temp) 
        *curr = new Node(temp->getValue());
        curr = &((*curr)->next);
        temp = temp->getNext();
    


virticalList::~virticalList() 
    Node* ptr = head, *next;
    while (ptr) 
        next = ptr->getNext();
        delete ptr;
        ptr = next;
    


virticalList& virticalList::operator=(const virticalList& p2)

    if (this != &p2) 
        virticalList temp(p2);
        //std::swap(head, temp.head);
        Node* ptr = head;
        head = temp.head;
        temp.head = ptr;
    
    return *this;


void virticalList::print() const

    Node* ptr = head;
    while (ptr) 
        cout << ptr->getValue() << " ";
        ptr = ptr->getNext();
    
    cout << "\n";


void virticalList::virtInc()

    Node* ptr = head;
    while (ptr) 
        ptr->setValue(ptr->getValue()+1);
        ptr = ptr->getNext();
    

Live Demo

【讨论】:

以上是关于使用等于运算符时遇到问题。以退出代码 11 结束 [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

为啥它停止并以退出代码 11 结束?

尽管正确打印出所有输出,但程序未在 Java 中以退出代码 0 结束

Android Studio Emulator崩溃:进程以退出代码139结束(由信号11中断:SIGSEGV)

Apple Watch 程序以退出代码结束:0

进程以退出代码 139 结束(被信号 11 中断:SIGSEGV)

进程在 PyCharm 中以退出代码 137 结束