C ++代码编译但运行时出现分段错误。我想我会破坏链接列表

时间:2014-04-12 02:23:42

标签: c++ linked-list stringstream

各位大家好,先发帖到这里。所以它进入周末,我无法访问我的课程讲师。这是我们使用链表的第一个项目,我很好地修改它。我很确定,错误是在sl_list.cpp output << temp -> contents();的第53行。这是为了访问节点的内容,在本例中为int,并将其存储在stringstream变量中,以便我可以以后输出整件事。显然,我做得不对。我一直试图在一天半的大部分时间内修复它,但我只是不知道我做错了什么。所有以“sl”开头的文件都是我的,exercise_18.cpp是测试我的教师创建的代码。如果我注释掉有问题的函数,我的代码将编译并按预期运行。谁能在这里告诉我我搞砸了什么?它可能很容易被发现。谢谢。

#include "sl_list.h"
#include <iostream>
#include <sstream>
using namespace std;
using std::stringstream;

SLList::SLList() {  // Sets head_ to NULL and size_ to 0
  head_ = NULL;
  size_ = 0;
}
SLList::~SLList() {  // Destructor for SLList
}
void SLList::InsertHead(int number) {  // Creates new dynamic SLNode
  SLNode* to_insert = new SLNode(number);
  to_insert -> set_next_node(head_);
  head_ = to_insert;
  size_++;
}
void SLList::RemoveHead() {  // Remove the SLNode from the list
  if (head_ != NULL) {  // Check for NULL
    SLNode* temp = head_;  // Storage for temp location
    head_ = head_ -> next_node();  // Set head to next_node
    delete temp;  // Delete temp storage
    size_--;  // Decrement size
  }
}
void SLList::Clear() {  // Clear the entire contents of the list
  if (head_ != NULL) {  // Check for NULL
    while (head_ != NULL) {  // Check for NULL
      SLNode* temp = head_;  // Storage for temp location
      head_ = head_ -> next_node();  // Set head to next_node
      delete temp;  // Delete temp storage
      size_--;  // Decrement size
    }
  }
}
unsigned int SLList::size() const {  // return size_
  return size_;
}
string SLList::ToString() const {  // returns the contents of all nodes
  if (head_ != NULL) {  // Check for NULL
    stringstream output;  // Storage for stringstream
    SLNode* temp = head_;  // Storage for temp location
      while (temp != NULL) {  // Check for NULL
        temp = temp -> next_node();  // Set head to next_node
        output << temp -> contents();  // Dumping temp into output
        if (temp != NULL) {  // Add a space and comma to the end of output
          output << ", ";
        }
      }
    return output.str();  // Return output
  } else {
    return "";  // If head_ was NULL return empty string
  }
}

#ifndef SL_LIST_H
#define SL_LIST_H

#include "sl_node.h"
#include <iostream>
using std::string;

class SLList {
 public:
  SLList();  // Default constructor
  ~SLList();  // Default destructor
  void InsertHead(int number);  // Creates new dynamic SLNode
  void RemoveHead();  // Remove the SLNode from the list
  void Clear();  // clear the entire contents of the list
  unsigned int size() const;  // Return size_
  string ToString() const;  // returns the contents of all nodes

 private:
  SLNode* head_;  // Storage for the next node locations
  unsigned int size_;  // Storage for the size
};

#endif /* SL_LIST.H */

#include "sl_node.h"
#include <iostream>

SLNode::SLNode() {  // Default constructor
  next_node_ = NULL;
  contents_ = 0;
}

SLNode::SLNode(unsigned int contents) {  // overloaded constructor
  next_node_ = NULL;
  contents_ = contents;
}

SLNode::~SLNode() {  // Empty destructor
}

void SLNode::set_contents(int contents) {  // Set contents_ to contents
  contents_ = contents;
}

int SLNode::contents() const {  // Return contents_
  return contents_;
}

void SLNode::set_next_node(SLNode* next_node) {  // Sets location of next node
  next_node_ = next_node;
}

SLNode* SLNode::next_node() const {  // Return next_node_
  return next_node_;
}

#ifndef SL_NODE_H
#define SL_NODE_H

class SLNode {
 public:
  SLNode();  // Default constructor
  SLNode(unsigned int contents);  // Overloaded constructor
  ~SLNode();  // Empty destructor
  void set_contents(int contents);  // Set contents_ to contents
  int contents() const;  // Return contents_
  void set_next_node(SLNode* next_node);  // Sets location of next node
  SLNode* next_node() const;  // Return next_node_

 private:
  SLNode* next_node_;  // Storage for the next node locations
  int contents_;  // Storage for the contents of the node
};

#endif /* SL_NODE.H */

#include "sl_list.h"
#include "sl_node.h"
#include <sstream>
#include <iostream>
using std::cout;
using std::endl;
using std::string;
using std::stringstream;

// For testing (DO NOT ALTER)
void Test(bool test, string more_info = "");
void UnitTest();

// Program Execution Starts Here
int main() {
  // To test your code (DO NOT ALTER)
  UnitTest();
  // This ends program execution
  return 0;
}

// For testing (DO NOT ALTER)
void UnitTest() {
  string temp = "This unit test will test some of your code:\n";
  cout << temp << string(temp.length() - 1, '-') << endl;
  // Tests
  SLList list;
  stringstream full_list, half_list;
  for (int i = 999; i > 0; i--) {
    full_list << i << ", ";
    if (i < 500)
      half_list << i << ", ";
  }
  full_list << 0;
  half_list << 0;

  Test(list.size() == 0, "Default Constructor & size()");
  Test(list.ToString() == "", "ToString()");

  list.RemoveHead();
  Test(list.size() == 0, "RemoveHead() & size()");

  list.InsertHead(1);
  Test(list.size() == 1, "InsertHead(1) & size()");
  Test(list.ToString() == "1", "ToString()");

  list.RemoveHead();
  Test(list.size() == 0, "RemoveHead() & size()");
  Test(list.ToString() == "", "ToString()");

  list.InsertHead(10);
  list.InsertHead(20);
  Test(list.size() == 2, "InsertHead(10), InsertHead(20) & size()");
  Test(list.ToString() == "20, 10", "ToString()");

  list.RemoveHead();
  Test(list.size() == 1, "RemoveHead() & size()");
  Test(list.ToString() == "10", "ToString()");

  list.InsertHead(5);
  Test(list.size() == 2, "InsertHead(5) & size()");
  Test(list.ToString() == "5, 10", "ToString()");

  list.Clear();
  Test(list.size() == 0, "Clear() & size()");
  Test(list.ToString() == "", "ToString()");

  for (unsigned int i = 0; i < 1000; i++)
    list.InsertHead(i);
  Test(list.size() == 1000, "InsertHead() \"HIGH LOAD\" & size()");
  Test(list.ToString() == full_list.str(), "ToString()");

  for (unsigned int i = 0; i < 500; i++)
    list.RemoveHead();
  Test(list.size() == 500, "RemoveHead() \"HIGH LOAD / 2\" & size()");
  Test(list.ToString() == half_list.str(), "ToString()");
  for (unsigned int i = 0; i < 600; i++)
    list.RemoveHead();
  Test(list.size() == 0, "RemoveHead() \"HIGH LOAD / 2\" & size()");
  Test(list.ToString() == "", "ToString()");

  cout << string(temp.length() - 1, '-') << endl;
  cout << "Unit Test Complete!\n\n";
}

// For testing (DO NOT ALTER)
void Test(bool test, string more_info) {
  static int test_number = 1;
  if (test)
    cout << "PASSSED TEST ";
  else
    cout << "FAILED  TEST ";
  cout << test_number << " " << more_info << "!\n";
  test_number++;
}

1 个答案:

答案 0 :(得分:0)

在输出循环中,在输出其值之前,您将临时移动到下一个节点。只需交换这两条线。

temp = temp -> next_node();  // Set head to next_node
output << temp -> contents();  // Dumping temp into output

应该成为

output << temp -> contents();  // Dumping temp into output
temp = temp -> next_node();  // Set head to next_node