【问题标题】:Singly linked list C++ ostream and istream -- outputs memory addresses单链表 C++ ostream 和 istream -- 输出内存地址
【发布时间】:2011-08-12 12:21:45
【问题描述】:

我对此真的很陌生,现在正在学习单链表。我正在写一些代码,但我真的很困惑。我正在尝试编写读取方法和写入方法。我有一个我无法更改的测试工具。我只是希望能够读取流并输出流,这样它就不会返回内存地址。

谁能用非常简单的方式解释一下并帮我修复这段代码?

void SLLIntStorage::Read(istream& r)
{
    char c[13];
    r >> c;
    r >> NumberOfInts;

    Node *node = new Node;
    head = node; //start of linked list

    for(int i = 0; i < NumberOfInts; i++) //this reads from the file and works
    {
        r >> node->data;
        cout << node->data << endl;
        node ->next = new Node; //creates a new node
        node = node->next;
    }
}

void SLLIntStorage::Write(ostream& w)
{
    Node *node = new Node;
    head = node;

    for(int i = 0; i < NumberOfInts; i++)
    {
        w << node->data << endl;
        //cout << i << endl;
    }
}

在头文件中

#pragma once

#include <iostream>

using namespace std;

struct Node
{
    int data; //data in current node
    Node *next; //link of address to next node
};

class SLLIntStorage
{

private:
    Node *head;// start of linked list
    //Node *tail;
    Node current; //current node
public:
    void setReadSort(bool);
    void sortOwn();

    void Read(istream&);
    void Write(ostream&);

    void add(int i);
    void del();

    bool _setRead;
    int NumberOfInts;

    SLLIntStorage(void);
    ~SLLIntStorage(void);
};

inline ostream& operator<< (ostream& out, SLLIntStorage& n) 
{
    n.Write(out); 
    return out;
}
inline istream& operator>> (istream& in, SLLIntStorage& s) 
{
    s.Read(in); 
    return in;
}

谢谢!

【问题讨论】:

  • 在您的 write 方法中,我看不到您在链表中的位置。看起来您缺少“node = node->next;”在你的循环中。如所写,您将重复写入相同的整数。
  • 你的测试输入是什么,当你运行它时你得到什么输出。另一件事是您的 Write 方法似乎没有遍历列表。只是一遍又一遍地打印相同的节点数据。看起来您的 Write 方法也将头节点设置为新节点。这将清除列表。
  • 另外,为什么要在write方法中创建节点?您的存储对象中应该已经有一个链表;即 SLLIntStorage::head。事实上,您的 write 方法会导致您现有的存储在用新节点覆盖“head”时泄漏。你的 write 方法应该假设“head”已经被你的 read 方法初始化了。

标签: c++ linked-list istream ostream


【解决方案1】:

您的 write 方法似乎有点混乱。 您想编写元素,而不是创建新元素。这样的事情应该会更好:

void SLLIntStorage::Write(ostream& w)
{
    Node *node = head;

    for(int i = 0; i < NumberOfInts; i++)
    {
        w << node->data << endl;
        node = node->next;
        //cout << i << endl;
    }
}

顺便说一句:你的实现方式似乎对我有用,你有一个潜在的大内存泄漏。一旦连续调用两次 Read 方法,旧列表将被丢弃而不释放内存。您应该考虑如果在保存另一个文件时调用 write,您的班级应该做什么。追加吗?先删除旧列表?

【讨论】:

  • 谢谢!现在可以了!看起来很简单,但 c++ 不是我的语言哈哈
  • 好的,谢谢提醒,我会考虑这个,我也会在某个时候放入一个析构函数,它应该做一些工作
  • 我想到的另一个建议:如果您费心考虑 const 的正确性,编译器会禁止您的错误。您的Write-方法可能是void Write(ostream&amp;) const,这样您就无法为head 分配新值。
【解决方案2】:

在您的 Write() 方法中,您可以通过以下方式破坏整个列表

Node *node = new Node;
head = node;

如果您问我,这会将整个列表替换为一个空列表。 NumberOfInts 不再正确,您继续打印相同的节点->数据 NumberOfInts 次。

我不知道从哪里开始。

【讨论】:

  • 但是Thilo 为您提供了一个起点:)
  • 另一个好点...嗯,还有很多事情要做。但是尝试一个接一个地解决问题。您的函数也不使用当前的 Node 类成员。
  • 好吧,我无法看到班级成员 current 的作业或访问权限。但也许您想稍后实现当前成员。对于在列表后面追加内容,保留指向最后一项的指针似乎是个好主意。
猜你喜欢
  • 2011-07-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-02-10
  • 2018-04-25
  • 1970-01-01
相关资源
最近更新 更多