Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/133.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 分段错误,在单链表中插入节点_C++_Insert_Segmentation Fault_Nodes_Singly Linked List - Fatal编程技术网

C++ 分段错误,在单链表中插入节点

C++ 分段错误,在单链表中插入节点,c++,insert,segmentation-fault,nodes,singly-linked-list,C++,Insert,Segmentation Fault,Nodes,Singly Linked List,我已经编写了一些代码,用于在第n个位置的单链表中插入节点,但是当我运行项目时,我收到一个分段错误:11 当n==到sizeM时,我调用push_back,它将在末尾插入节点。当n==为0时,我调用push_字体,它将在开始时输入insert节点。这两个函数都可以工作,因为我在主文件的前面调用了它们进行检查。在我打电话插入我的列表之前 440 330 110 headM指向440,这是列表中的第0个位置 然后我打3个电话插入 插入40,3 插入10,0 插入33,2 现在的名单应该是10440 3

我已经编写了一些代码,用于在第n个位置的单链表中插入节点,但是当我运行项目时,我收到一个分段错误:11

当n==到sizeM时,我调用push_back,它将在末尾插入节点。当n==为0时,我调用push_字体,它将在开始时输入insert节点。这两个函数都可以工作,因为我在主文件的前面调用了它们进行检查。在我打电话插入我的列表之前

440 330 110

headM指向440,这是列表中的第0个位置

然后我打3个电话插入

插入40,3

插入10,0

插入33,2

现在的名单应该是10440 33 330 110 40

我不确定出了什么问题,但我很确定当我插入33时,这是应该做的事情

这是我的simpleList.h,包含类

#ifndef Lab9_Simple_List__SimpleList__
#define Lab9_Simple_List__SimpleList__

typedef int ListItem;

class SimpleList {
private:

class Node {
public:
    ListItem item;
    Node *next;
};

Node *headM;
int sizeM;

void destroy();
// Deallocate all nodes, and sets headM to zero.

void copy(const SimpleList& source);
// List becomes copy of source.

public:

SimpleList(): headM(0), sizeM(0) { /* Point one */}
// PROMISES: creates empty list.

SimpleList(const SimpleList& source) { copy(source); }// copy constructor

SimpleList& operator =(const SimpleList& rhs);  // assignment operator

~SimpleList() { destroy(); }   // destructor

int size() const {return sizeM;}

void push_back(const ListItem& item);
// PROMISES:
//    Adds a node with an item to the end of the list, and increments sizeM

void push_front(const ListItem& item);
// PROMISES:
//    Adds a node with an item to the beginning of the list, and increments
//    sizeM
void pop_back(const ListItem& item);
// PROMISES:
//    The last node int list is removed

const ListItem& at(int n)const;
// PROMISES:
//    An item is return at the nth position in the list.
//    if n is less than 0 or greater than or equal sizeM gives the error
//    message: "Illegal Access" and terminates the program

ListItem& at(int n);
// PROMISES:
//    An item is return at the nth position in the list.
//    if n is less than 0 or greater than or equal sizeM gives the error
//    message: "Illegal Access" and terminates the program

void insert(const ListItem& theItem, int n);
// PROMISES:
//    A node with a copy of theItem is inserted at the nth position, and sizeM
//    will be incremented if the operation of insert was successfull.
//    if n == sizeM calles push_back
//    if n == 0 calls push_front
//    if n < 0 or n > sizeM returns and does nothing.

void remove(int n);
//  PROMISES:
//    Does nothing if n < 0 or n > sizeM-1. Otherwise, if list is not empty
//    removes the node at the position n.
};

#endif /* defined(Lab9_Simple_List__SimpleList__) */

问题在void SimpleList::removeint的第一行


如果调用该函数时n正好是堆栈的大小,这在移除3时发生在main中,则情况类似。当p已经为null ptr时,您试图访问p->next的次数过多

对纯文本进行缩进和常规格式设置。还有,你确定这是一个最小的例子吗?请参阅:辅助缩进。不过,就MCVE而言,如果他能找到并提供MCVE,他很可能不会有问题:。@Deduplicator我之前问过这个问题,每个人都说提供一个完整的示例,所以我have@tomsmith给出完整的示例并不意味着您应该在这里抛出所有代码,而是给出一个最小的示例,这是完全可编译的,并且重现了问题。调试器还有助于缩小问题的范围。顺便说一句,这里有很多问题需要解决lists@JonathanMee:没有什么反复无常的。他们的意思是,他之前没有完成最小完整可验证示例的完整部分。这并不意味着他应该完全不及格,也不意味着他不应该使用正确的缩进和格式。-将其更改为>=有效!!我原以为我的插页有问题,但实际上是我的删除。谢谢
#include <iostream>
using namespace std;

#include <stdlib.h>
#include "SimpleList.h"


SimpleList& SimpleList::operator =(const SimpleList& rhs)
{
if (this != &rhs) {
    destroy();
    copy(rhs);
}

sizeM = rhs.sizeM;
return *this;
}

ListItem& SimpleList::at(int n)
{
if(n < 0 || n >= sizeM)
{
    cout << "\n Illegal Access. Program Terminates...";
    exit(1);
}

Node * p = headM;
for(int i= 0; i < n; i++)
    p = p -> next;

// point four

return p -> item;
}

const ListItem& SimpleList::at(int n)const
{
if(n < 0 || n >= sizeM){
    cout << "\n Illegal Access. Program Terminates...";
    exit(1);
}

Node * p = headM;
for(int i= 0; i < n; i++)
    p = p -> next;

// point three - when reached for the first time
return p -> item;
}

void SimpleList::push_back(const ListItem& item)
{
Node *new_node = new Node;
if(new_node == NULL)
{
    cout << "\nNo memory available to create a node" << endl;
    exit(1);
}

new_node->item = item;

if (headM == 0) {
    new_node->next = headM;
    headM = new_node;
}
else
{
    Node* p = headM;
    while (p ->next  != NULL)
        p = p ->next;

    p -> next = new_node;
    new_node -> next = NULL;
}
sizeM++;

// point five - when reached for the third time
}


void SimpleList::push_front(const ListItem& item)
{
Node *new_node = new Node;
new_node->item = item;
new_node->next = headM;
headM = new_node;
sizeM++;

// point two
}

void SimpleList::destroy()
{

// This function is not properly designed.
cout << "\nSimpleList::destroy was called but didn't do the right job.";
headM = 0;
}


void SimpleList::copy(const SimpleList& source)
{

// this function is incomplete and is not properly designed. It doesnt do
// its job, makeing 'this' SimpleList object a copy of the scoure.

// The only effect of the next line is to tell the compiler
// not to generate an "unused argument" warning.  If you are going to complete
// this funciton, don't leave it in your solution.
(void) source;

cout << "\nSimpleList::copy was called but didn't do the right job."
<< "--program is terminated.\n";
exit(1);
}

void SimpleList::insert(const ListItem& theItem, int n)
{
if (n < 0 || n > sizeM)
    return;
else if (n == sizeM)
    push_back(theItem);
else if (n == 0)
    push_front(theItem);
else
{
    Node* new_node = new Node;
    new_node->item = theItem;
    Node* temp = headM;
    for(int i = 0; i < (n - 1) ; i++)
    {
        temp = temp->next;
    } 
    new_node->next = temp->next;
    temp->next = new_node;
    sizeM++;
}
}

void SimpleList::remove(int n)
{
if( n < 0 || n > sizeM ) { 
    return;
}

Node* p = headM;

if(n == 0 && headM != NULL)
{
    Node* const p_doomed = headM;
    headM = p_doomed->next;
    delete p_doomed;
    --sizeM;
}
else{
    for(int c = 0; c < n - 1; c++ )
    {
        p = p->next;
    }
    Node* const p_doomed = p->next;
    p->next = p_doomed->next;
    delete p_doomed;
    --sizeM;
}
}
#include <iostream>
#include <iomanip>
using namespace std;
#include "SimpleList.h"
#define EXERCISE_B

void print(const SimpleList& list);
// PROMISES: prints values in the list from first node (node number 0) to
//           the last node. 

int main()
{    
SimpleList list;

cout << "\nList just after creation -- is empty.";

list.push_front(50);
cout << "\nAfter calling push_front. list must have: 50\n";
print(list);

list.push_back(440);

list.at(0) = 770;
cout << "\nAfter calling push_back and at functions, list must have: 770  440\n";
print(list);

list.push_back(330);
list.push_back(220);
list.push_back(110);

cout << "\nAfter three more calls to push_back, list must have:"
"770, 440, 330, 220, 110\n";
print(list);

#if defined (EXERCISE_B)
list.remove(0);
list.remove(2);
cout << "\nAfter removing two nodes. list must have: 440, 330, 110\n";
print(list);
list.insert(40, 3); //insert node with the value of 40 at the 4th position
list.insert(20, -1); // do nothing
list.insert(30, 30000); // do nothing
list.insert(10, 0); //insert node with the value of 10 at the 1st position
list.insert(33, 2); // insert node with the value 33 at the 3rd position

cout << "\nTwo  more nodes inserted, must have: 10, 440, 33, 330, 110, 40\n";
print(list);

list.remove(0);
list.remove(1);
list.remove(2);
list.remove(3);
list.remove(4);
list.remove(5);
cout << "\nAfter 6 removes, list must have: 440, 330, 40: \n";
print(list);

#endif
return 0;

}


void print(const SimpleList& list)
{
for(int i = 0; i < list.size(); i++)
    cout << list.at(i) << "  ";
}
Haydns-MacBook-Pro:desktop Haydn$ g++ lab9_EXE_A.cpp simpleList.cpp
Haydns-MacBook-Pro:desktop Haydn$ ./a.out 

List just after creation -- is empty.
After calling push_front. list must have: 50
50  
After calling push_back and at functions, list must have: 770  440
770  440  
After three more calls to push_back, list must have:770, 440, 330, 220, 110    
770  440  330  220  110  
After removing two nodes. list must have: 440, 330, 110
440  330  110  
Two  more nodes inserted, must have: 10, 440, 33, 330, 110, 40
Segmentation fault: 11
if (n < 0 || n >= sizeM) {  // CHange to >= and not > !!!
...
p=headM;   // meaning that p is now nullptr
if (n == 0 && headM != NULL)  // false because `n==0 && headM==nullptr`
// if block ignored 
else{  // here: (n!=0 || headM==NULL)  
    for (int c = 0; c < n - 1; c++) // the condition is false 
    // the loop body is ignored
    Node* const p_doomed = p->next;  // ouch !!!! p is nullptr => segfault !!!