【问题标题】:Confusion with delete functionality in c++与 C++ 中的删除功能混淆
【发布时间】:2017-07-26 18:57:49
【问题描述】:

所以我用c++写了这段代码

#include "ContactBook.hpp"

int main(){

    std::string name;
    ContactList *cl1 = new ContactList();

    while(true){

        std::cout << "Enter a name or press Q to quit" << std::endl;
        std::cin >> name;

        if(name=="Q"||name=="q")
            break;
        else{
            cl1->addToHead(name);
        }
    }

    cl1->print();
    delete cl1;

    return 0;
}

我的头文件定义->

#ifndef ContactBook_hpp
#define ContactBook_hpp

#include <iostream>

class Contact{
    friend std::ostream &operator<<(std::ostream &os, const Contact &c);
    friend class ContactList;
public:
    Contact(std::string name);
private:
    std::string name;
    Contact* next;
};

class ContactList{
public:
    ContactList();
    void addToHead(const std::string &name);
    void print();
private:
    Contact *head;
    static int size;
};

#endif

现在这是我的头文件函数定义。 ContactList 和 Contact 是两个类。联系人列表是联系人的朋友类。

#include "ContactBook.hpp"

Contact::Contact(std::string name){
    this->name = name;
    next = NULL;
}
std::ostream &operator<<(std::ostream &os, const Contact &c){
    os << "Name: " << c.name << std::endl;
    return os;
}

ContactList::ContactList():head(NULL){};
int ContactList::size = 0;

void ContactList::addToHead(const std::string &name){

    Contact *newOne = new Contact(name);

    if(head==NULL){
        head = newOne;
    }
    else{
        newOne->next = head;
        head = newOne;
    }
    ++size;

}

void ContactList::print(){

    Contact *temp;
    temp = head;

    while(temp!=NULL){
        std::cout << *temp;
        temp = temp->next;
    }
}

问题是每当我添加

delete newOne;

在 addToHead 定义中的第三个代码 sn-p 中的 ++size 之后。

我最终会在名称的奇数输入(1 除外)上出现无限循环!我只是不明白为什么会这样!对此的一些知识将不胜感激:D!

【问题讨论】:

  • 为什么要删除刚刚添加的节点?这会在列表的前面留下一些垃圾内存。
  • 必须提及std::unique_ptr 为您进行内存管理。
  • 如果您删除该节点,您将删除列表中的头部。在main 中,在addToHead 之后,您调用print。此函数尝试循环遍历您的列表,从您删除的头部开始。使用已删除的对象是未定义的行为,因此任何事情都可能发生。这包括永远循环。
  • @0x5453,但不一定适用于链表。
  • @SergeyA 我很好奇你为什么不推荐 std::unique_ptr 用于链表?

标签: c++ c++11 linked-list c++14 delete-operator


【解决方案1】:

在这里,在您的 addToHead 中:

Contact *newOne = new Contact(name);

if(head==NULL){
    head = newOne;
}
else{
    newOne->next = head;
    head = newOne;
}
++size;

可以这样写:

Contact *newOne = new Contact(name);

newOne->next = head; // if (head==NULL) newOne->next=NULL else newOne->next=head;
head = newOne;
++size;

您将 newOne 的值分配给 head。

但是如果你添加delete,就像你说的,在++size之后,head会指向被删除的东西。

在您的打印方法中发生的情况是您取消引用已删除的内容。 当您取消引用已删除的内容时会发生未定义的行为,这可能会导致奇怪的输出或崩溃。

您可能希望使用smart pointers 来避免访问已删除的内存和内存泄漏。

【讨论】:

  • 老兄,非常感谢!我刚刚意识到问题:D
猜你喜欢
  • 1970-01-01
  • 2021-05-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-07
  • 2011-03-09
相关资源
最近更新 更多