【问题标题】:Creation of LInked List链接列表的创建
【发布时间】:2019-06-09 11:27:38
【问题描述】:

我想显示字符串“Jimmy”但什么也没有出现。我的错误是什么?

#include<iostream>
#include<string>

struct Node 
{
    std::string s;
    Node* next;
};
struct  Node* head = NULL;

void insert(const std::string& name) 
{
    struct Node* newnode = (struct Node*)malloc(sizeof(struct Node));
    newnode->s = name;
    newnode->next = NULL;
    head = newnode;
}

void display() 
{
    struct Node* ptr;
    ptr = head;
    while (ptr != NULL) {
        std::cout << ptr->s << std::endl;
    }
}

int main() 
{
    insert("Jimmy");
    display();
    return 0;
}

此代码中未显示任何输出。请给一些建议。我还是这个数据结构的新手。

【问题讨论】:

  • 您似乎是一名 C 程序员,正在转向 C++。这两种语言是截然不同的。所以我建议不要过多依赖你的 C 知识,并从our curated book list 中挑选一本书。​​
  • 如果你需要一个链表,你应该使用std::list。但是,在大多数情况下,链表是一种非常低效的数据结构,通常使用std::vector 会更好。还; 不要在 C++ 中使用malloc,并且更喜欢nullptr 而不是NULL
  • 在我的机器上按原样运行代码会导致无限循环不断打印Jimmy。我认为这是因为在display 中,您没有将ptr 推进到ptr-&gt;next
  • 第一个错误是使用malloc。您不能使用malloc 分配非平凡的C++ 类型,std::string 就是其中之一。根据经验,永远不要使用mallocfree

标签: c++ struct linked-list new-operator singly-linked-list


【解决方案1】:

标准 C 函数 malloc 分配原始内存,对将被放置在内存中的对象一无所知。

所以不会调用对象的构造函数。

结构节点包含std::string 类型的数据成员,应为其调用构造函数。

在 C++ 中,使用运算符 new 而不是调用 C 函数 malloc。运算符不仅分配内存,还为创建的对象调用构造函数。

在函数定义中使用全局对象而不通过参数传递它们是一个坏主意。

head不等于空指针时,函数display可以有一个无限循环,因为循环中使用的变量ptr(分配了head)没有改变。

void display() 
{
    struct Node* ptr;
    ptr = head;
    while (ptr != NULL) {
        std::cout << ptr->s << std::endl;
    }
}

函数insert只能调用一次

void insert(const std::string& name) 
{
    struct Node* newnode = (struct Node*)malloc(sizeof(struct Node));
    newnode->s = name;
    newnode->next = NULL;
    head = newnode;
}

否则会导致内存泄漏

您应该在退出程序之前释放节点。

这是一个修改过的程序,它没有原始程序的缺点。

#include <iostream>
#include <string>

struct Node
{
    std::string s;
    Node *next;
};

void insert( Node * &head, const std::string &s )
{
    head = new Node { s, head };
}

std::ostream & display( const Node * head, std::ostream &os = std::cout )
{
    for ( const Node *current = head; current != nullptr; current = current->next )
    {
        os << current->s << '\n';
    }

    return os;
}

void clear( Node * &head )
{
    while ( head )
    {
        Node *tmp = head;
        head = head->next;
        delete tmp;
    }
}

int main() 
{
    Node *head = nullptr;

    insert( head, "Jimmy" );

    display( head );

    clear( head );

    return 0;
}

它的输出是

Jimmy

【讨论】:

  • 甚至比使用new 更好;尽可能分配自动对象(在堆栈上)。如果不能,请使用智能指针 (std::unique_ptr/std::shared_ptr)。手动内存管理是 1990 年代的事,而且容易出错。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-05
  • 2023-03-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多