[英]Stack implementation in C++ using a class causing segmentation fault
I have implemented some functions for a Stack in C++. 我已经在C ++中实现了一些Stack功能。 I am unsure as to why I am getting a segmentation fault.
我不确定为什么会出现细分错误。 Right now, I have 7 different files: node.h, node.cpp, LL.h, LL.cpp, Stack.h, Stack.cpp and main.cpp which I am using to test LL.cpp and Stack.cpp.
现在,我有7个不同的文件:node.h,node.cpp,LL.h,LL.cpp,Stack.h,Stack.cpp和main.cpp,这些文件用于测试LL.cpp和Stack.cpp。 If anyone could direct me to the error, I would really appreciate it.
如果有人可以引导我指出错误,我将不胜感激。 Here are the codes:
以下是代码:
node.h : node.h:
// node.h
class node { // node class used in the LL (linked list) class
private:
node * next; // Pointer to next node of an LL
int data; // integer data stored in this node
public:
node(int x, node * n); // Constructor
~node(); // Destructor
void set_data(int x); // Change the data of this node
void set_next(node * n);// Change the next pointer of this node
int get_data(); // Access the data of this node
node * get_next(); // Access the next pointer of this node
};
LL.h : LL.h:
// LL.h
#include "node.h"
// Linked list class, used in the Stack class
class LL {
private:
node * head; // pointer to first node
node * tail; // pointer to last node
public:
LL(); // Constructor
~LL(); // Destructor
void prepend(int value); // add a node to the beginning of the LL
int removeHead(); // remove the first node of the LL
void print(); // print the elements of the LL
node * get_head(); // access the pointer to the first node of the LL
};
Stack.h: Stack.h:
// Stack.h
#include "LL.h"
class Stack {
private:
LL * intlist;
public:
Stack(); // Constructor
~Stack(); // Destructor
void push(int value);
int pop();
int isEmpty();
void Sprint();
};
Stack.cpp: Stack.cpp:
// Stack.cpp
#include "Stack.h"
#include <stdio.h>
Stack::Stack() {
}
Stack::~Stack() {
}
int Stack::isEmpty() {
return ( (intlist->get_head()) ==NULL);
}
void Stack::push(int value) {
intlist->prepend(value);
}
int Stack::pop() {
if ( ! isEmpty() ) {
int result=intlist->removeHead();
return result;
}
return -1;
}
void Stack::Sprint() {
intlist->print();
}
And here is the main.cpp that I am using to test it: 这是我用来测试的main.cpp:
// main.cpp
#include "Stack.h"
#include <stdio.h>
int main() {
LL a;
a.prepend(3);
a.prepend(4);
a.prepend(5);
a.print();
a.removeHead();
a.print();
Stack sta;
sta.pop();
sta.push(3);
sta.push(4);
sta.push(10);
sta.Sprint();
printf("Popping %d\n", sta.pop());
sta.Sprint();
sta.pop();
printf("Stack empty? %d\n", sta.isEmpty());
sta.pop();
printf("Stack empty? %d\n", sta.isEmpty());
return 0;
}
I have been trying to find what's causing the segmentation fault for a while. 我一直在尝试查找导致分段错误的原因。 Any help appreciated
任何帮助表示赞赏
This program is crashing because your Stack
class never initializes the Linked List pointer ( LL * intlist
), so when you check if it's empty it tries referencing garbage: 该程序崩溃是因为您的
Stack
类从不初始化链接列表指针( LL * intlist
),因此当您检查它是否为空时,它将尝试引用垃圾:
Stack.pop() => Stack.isEmpty() => intlist->isEmpty() => segfault
You could just make it a member instead of a pointer (recommended): 您可以使它成为成员而不是指针(推荐):
class Stack {
private:
LL intlist; // There's no need for it to be a pointer
public:
Stack(); // Constructor
~Stack(); // Destructor
void push(int value);
int pop();
int isEmpty();
void Sprint();
};
Alternatively, you could initialize it in the constructor and delete it in the destructor. 另外,您可以在构造函数中对其进行初始化,而在析构函数中将其删除。 You should really only do this when a member variable needs to be a pointer;
实际上,只有在成员变量需要为指针时才应该这样做。 otherwise you should just store it regularly.
否则,您应该定期存储它。
Stack::Stack() : intlist(new LL()) {
}
Stack::~Stack() {
delete intlist;
}
Pointer intlist
in Stack
is never initialized, so attempting to dereference it caused your segfault (in this case, it was when sta.pop()
was first called). Stack
指针intlist
从未初始化,因此尝试对其进行取消引用会导致您的段错误(在这种情况下,是第一次调用sta.pop()
时)。
You could allocate memory for intlist
in Stack
's constructor (eg intlist = new LL;
) and delete it when you're done (or use a smart pointer instead). 您可以在
Stack
的构造函数中为intlist
分配内存(例如, intlist = new LL;
),并在完成intlist = new LL;
其删除(或使用智能指针)。 But in this case that'll do more harm than good. 但是在这种情况下,弊大于利。
You're likely better off defining intlist
as an object of type LL
, not a pointer to it, in Stack
: 您最好在
Stack
intlist
定义为LL
类型的对象,而不是指向它的指针:
class Stack {
private:
LL intlist;
...
};
Of course, don't forget to replace all arrow operators ( ->
) with dot operators ( .
) when working with intlist
. 当然,在使用
intlist
时,请不要忘记将所有箭头运算符( ->
)替换为点运算符( .
)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.