链表 (c++) 的分段错误
Segmentation fault with linked list (c++)
当以下程序运行时,我得到一个分段错误。 问题到底出在哪里?
头文件:
#ifndef MAIN_SAVITCH_NODE1_H
#define MAIN_SAVITCH_NODE1_H
#include <cstdlib> // Provides size_t and NULL
namespace main_savitch_5
{
class node
{
public:
// TYPEDEF
typedef double value_type;
// CONSTRUCTOR
node(
const value_type& init_data = value_type(),
node* init_link = NULL
)
{
data_field = init_data; link_field = init_link;
}
// Member functions to set the data and link fields:
void set_data(const value_type& new_data) { data_field = new_data; }
void set_link(node* new_link) { link_field = new_link; }
// Constant member function to retrieve the data:
value_type data() const { return data_field; }
// Constant member functions to retrieve the link:
node* link() const { return link_field; }
private:
value_type data_field;
node* link_field;
};
// FUNCTIONS for the linked list toolkit
std::size_t list_length(const node* head_ptr);
void list_head_insert(node*& head_ptr, const node::value_type& entry);
void list_insert(node* previous_ptr, const node::value_type& entry);
node* list_search(node* head_ptr, const node::value_type& target);
node* previous_to_min(node* marker_ptr);
node* list_locate(node* head_ptr, std::size_t position);
void list_head_remove(node*& head_ptr);
void list_remove(node* previous_ptr);
void list_clear(node*& head_ptr);
void list_copy(const node* source_ptr, node*& head_ptr, node*& tail_ptr);
void print_list(const node* head_ptr);
}
#endif
实现文件(这些都不是我的)
#include "node1.h"
#include <cassert> // Provides assert
#include <iostream>
#include <cstdlib> // Provides NULL and size_t
using namespace std;
namespace main_savitch_5
{
size_t list_length(const node* head_ptr)
// Library facilities used: cstdlib
{
const node *cursor;
size_t answer;
answer = 0;
for (cursor = head_ptr; cursor != NULL; cursor = cursor->link())
++answer;
return answer;
}
void print_list(const node* head_ptr)
{
const node *cursor;
cout << endl;
for (cursor = head_ptr; cursor != NULL; cursor = cursor->link()) cout << cursor->data() << " ";
cout << endl;
}
void list_head_insert(node*& head_ptr, const node::value_type& entry)
{
head_ptr = new node(entry, head_ptr);
}
void list_insert(node* previous_ptr, const node::value_type& entry)
{
node *insert_ptr;
insert_ptr = new node(entry, previous_ptr->link());
previous_ptr->set_link(insert_ptr);
}
node* list_search(node* head_ptr, const node::value_type& target)
// Library facilities used: cstdlib
{
node *cursor;
for (cursor = head_ptr; cursor != NULL; cursor = cursor->link())
if (target == cursor->data())
return cursor;
return NULL;
}
node* previous_to_min(node* marker_ptr)
{
node * cursor;
node * pre_cursor;
node * current_min_prev_cursor;
int current_min;
pre_cursor = marker_ptr;
cursor = marker_ptr->link();
current_min = cursor->data();
current_min_prev_cursor = pre_cursor;
while (cursor != NULL)
{
if (cursor->data() < current_min)
{
current_min = cursor->data();
current_min_prev_cursor = pre_cursor;
}
pre_cursor = cursor;
cursor = cursor->link();
}
return current_min_prev_cursor;
}
node* list_locate(node* head_ptr, size_t position)
// Library facilities used: cassert, cstdlib
{
node *cursor;
size_t i;
assert(0 < position);
cursor = head_ptr;
for (i = 1; (i < position) && (cursor != NULL); i++)
cursor = cursor->link();
return cursor;
}
void list_head_remove(node*& head_ptr)
{
node *remove_ptr;
remove_ptr = head_ptr;
head_ptr = head_ptr->link();
delete remove_ptr;
}
void list_remove(node* previous_ptr)
{
node *remove_ptr;
remove_ptr = previous_ptr->link();
previous_ptr->set_link(remove_ptr->link());
delete remove_ptr;
}
void list_clear(node*& head_ptr)
// Library facilities used: cstdlib
{
while (head_ptr != NULL)
list_head_remove(head_ptr);
}
void list_copy(const node* source_ptr, node*& head_ptr, node*& tail_ptr)
// Library facilities used: cstdlib
{
head_ptr = NULL;
tail_ptr = NULL;
// Handle the case of the empty list.
if (source_ptr == NULL)
return;
// Make the head node for the newly created list, and put data in it.
list_head_insert(head_ptr, source_ptr->data());
tail_ptr = head_ptr;
// Copy the rest of the nodes one at a time, adding at the tail of new list.
source_ptr = source_ptr->link();
while (source_ptr != NULL)
{
list_insert(tail_ptr, source_ptr->data());
tail_ptr = tail_ptr->link();
source_ptr = source_ptr->link();
}
}
}
和我的主文件
#include <cstdlib>
#include <ctime>
#include <iostream>
#include <cassert>
#include "node1.h"
using namespace main_savitch_5;
void list_sort(node* &head_ptr);
int main()
{
unsigned seed = time(0);
size_t n;
node *head;
node *current;
srand(seed);
std::cout << "How many items would you like to sort?n";
std::cin >> n;
assert(n > 0); // Ensure the list is not empty
list_head_insert(head, 1 + rand() % 1000);
current = head;
for (size_t i = 1; i < n; i++)
{
list_insert(current, (1 + rand() % 1000));
current = current->link();
}
std::cout << "Unsorted list:n";
print_list(head);
list_sort(head);
std::cout << "Sorted list:n";
print_list(head);
list_clear(head);
return 0;
}
void list_sort(node* &head_ptr)
{
node* marker;
node* min_node;
node* temp;
node* cursor;
min_node = previous_to_min(head_ptr);
// Set a pointer to the minimum data value in the list
if (head_ptr->data() < min_node->data())
marker = head_ptr;
else
{
// If the head pointer does not hold the smallest value,
// swap it with the node containing the min value
temp = min_node->link();
min_node->set_link(temp->link());
temp->set_link(head_ptr);
head_ptr = temp;
marker = head_ptr;
}
while (marker->link()->link() != NULL)
{
cursor = previous_to_min(marker);
// Find the smallest value of our new sublist
if (cursor == marker)
marker = marker->link();
else
{
// Swap the head of the sublist with the new min value
temp = cursor->link();
cursor->set_link(temp->link());
temp->set_link(marker->link());
marker->set_link(temp);
marker = marker->link();
}
}
}
分段错误在首次调用 print_list() 后立即发生。
问题是您在列表开始时的链接节点未设置为 NULL:
在main
函数中,您有以下内容:
node *head;
//...
list_head_insert(head, 1 + rand() % 1000);
但是,list_head_insert
函数使用第一个参数的值来设置下一个链接。
void list_head_insert(node*& head_ptr, const node::value_type& entry)
{
head_ptr = new node(entry, head_ptr);
}
由于指针未初始化,因此在调用 list_head_insert
之前设置的任何垃圾都用作创建新node
时的head_ptr
,如下所示:
node(const value_type& init_data = value_type(),
node* init_link = NULL)
{
data_field = init_data;
link_field = init_link; // oh no.
}
最终发生的是,添加到链表中的每个新节点都依赖于前一个节点的链接值。 因此,当您构建链表时,这个错误的链接值会在节点之间传递,并最终用作列表的哨兵节点。
由于哨兵节点具有垃圾值,因此在节点为 NULL 时停止的循环都是错误的(因为没有 NULL)。
所以解决方案是在main
开始时将head
节点设置为 NULL:
node *head = NULL;
现在,这会将链接设置为 NULL,然后此值将用作哨兵节点。
相关文章:
- 在某些循环内使用vector.push_back时出现分段错误
- 为什么在运行时没有向我们提供有关分段错误的更多信息?
- 如何解决gcc编译器优化导致的centos双编译器设置中的分段错误
- 当我的阵列太大时出现分段错误
- 分段错误当我试图运行程序时出错
- 在c++中初始化矩阵时出现分段错误(核心转储)
- 尝试使用集合函数时出现分段错误
- 我无法缩小此分段错误的原因
- g++的分段错误(在NaN上使用to_string两次时)
- 我是如何在这段代码中出现分段错误的
- 创建结构的数组时遇到分段错误
- 在c++中键入向量中的所有值后,得到分段错误(核心转储)
- 在 c++ 中实现 Trie 时出现分段错误
- 为什么 fstream 在打开带有格式的文件时会导致分段错误?
- 为什么我遇到分段错误?
- 动态类的分段错误(家庭作业问题)
- 分段错误 - 读取初始化指针的数组
- 如何摆脱C ++中的分段错误错误?
- 使用 CTYPE 时出现分段错误
- 为什么代码给出分段错误?