简体   繁体   English

Segmentation Fault错误-使用链接列表实现堆栈

[英]Segmentation Fault error - Implementing Stack using Linked lists

I am currently in a University program studying Data Structures in C and I am having a lot of trouble right now. 我目前正在大学课程中学习C语言中的数据结构,现在遇到很多麻烦。 I want to make clear that what I am asking help for is not for marks, just practice challenge problems. 我想明确指出,我要寻求帮助的不是分数,而只是练习挑战性问题。

The goal is to implement a stack using Linked Lists. 目标是使用链接列表实现堆栈。 By looking through the lecture notes I think I have most of the functions down. 通过阅读讲义,我认为我掌握了大部分功能。 I need to demonstrate Push() and Pop() will an append and a pretend. 我需要演示Push()和Pop()将追加和伪装。 Using Cygwin, I compiled with no errors. 使用Cygwin,我编译时没有错误。 but when I try to run it, I get a "Segmentation Fault". 但是当我尝试运行它时,出现“分段错误”。 What does this mean and how do I fix it? 这是什么意思,我该如何解决? if I remove "stack = initLListStack();", the error disappears. 如果删除“ stack = initLListStack();”,该错误消失。 Here is my code: 这是我的代码:

#include <stdio.h>
#include <stdlib.h>

typedef struct Link{
int *value;
struct Link *next;
}Link;

typedef struct LList1{
int *size;
Link *head;
}LList1;

typedef struct LListStack{
LList1 *llist;
}LListStack ;


LListStack *initLListStack(void)
{
LListStack *stack = (LListStack *) malloc(sizeof(LListStack)) ;
stack->llist->size = 0;
stack->llist->head = NULL;
return(stack);
}


void removefront(LList1 *llist)
{
if(llist->head != NULL){
    llist->head = llist->head->next;
    llist->size--;
}
}

Link *FindLastLink(LList1 *llist, Link *link)
{
if(link = NULL){
    return(NULL);
}
else if(link->next == NULL){
    return(link);
}
else{
    return(FindLastLink(llist, link->next));
}
}

Link *FindSecondLastLink(LList1 *llist, Link *link)
{
if(link = NULL){
    return(NULL);
}
else if(link->next->next == NULL){
    return(link);
}
else{
    return(FindSecondLastLink(llist, link->next));
}
}

void removelast(LList1 *llist)
{
Link *secondlastlink = (Link *) malloc(sizeof(Link));
secondlastlink = FindSecondLastLink(llist, llist->head);
secondlastlink->next = NULL;
llist->size--;

}



void prepend(int *newValue, LList1 *templist)
{
Link *node = (Link *) malloc(sizeof(Link)); 
node->value = newValue; 
node->next = templist->head;
templist->head = node;
templist->size++;
}

void append(int *newValue, LList1 *templist)
{
Link *node = (Link *) malloc(sizeof(Link));
Link *lastlink = (Link *) malloc(sizeof(Link));
lastlink = FindLastLink(templist, templist->head);
node->value = newValue;
lastlink->next = node;
node->next = NULL;
templist->size++;
}

void prepush(int *value, LListStack *stack)
{
 prepend(value, stack->llist);
}

void apppush(int *value, LListStack *stack)
{
append(value, stack->llist);
}

int prepop(LListStack *stack, int *value)
{ 
int result ;

if ((!isEmpty(stack)))
{
    removefront(stack->llist);
    result = 1 ;

}
else {
    result = 0 ;
}
return(result) ;
}

int isEmpty(LListStack *stack) 
{ 
int empty;

if (stack->llist->head == NULL) 
    return( 1 ) ;
else
    return( 0 ) ;
}

int apppop(LListStack *stack, int *value)
{ 
int result ;

if ((!isEmpty(stack)))
{
    removelast(stack->llist);
    result = 1 ;
}
else 
    result = 0 ;

return(result) ;
}

//*******MAIN**********//

int main()
{
LListStack *stack = (LListStack *) malloc (sizeof(LListStack));

stack = initLListStack(); //if I take this away, I can run the program


return(0);
}

I don't have that much in Main() yet because I'm just trying to get it to run first. 我在Main()中还没有那么多,因为我只是想让它首先运行。 Initializing the Stack seems to be the problem. 初始化堆栈似乎是问题所在。

Thanks for your help guys! 感谢您的帮助!

The problem is in your initLListStack() function: 问题出在您的initLListStack()函数中:

LListStack *stack = (LListStack *) malloc(sizeof(LListStack)) ;
stack->llist->size = 0;
stack->llist->head = NULL;
return(stack);

The result of malloc is an uninitialized block of memory large enough to hold an LListStack struct. malloc的结果是未初始化的内存块,其大小足以容纳LListStack结构。

The very first thing you do with that memory is read its llist member. 使用该内存的第一件事是读取其llist成员。 Since this is uninitialized, you invoke undefined behavior which, fortunately, causes a segfault. 由于这是未初始化的,因此您需要调用未定义的行为,这会导致段错误。 (The compiler would be within the specification to send embarrassing e-mails to our instructor when this happens.) (发生这种情况时,编译器将在规范内发送令人尴尬的电子邮件给我们的讲师。)

You need to initialize llist before you can use that member in stack. 您需要先初始化llist然后才能在堆栈中使用该成员。 Something like: 就像是:

LListStack *stack = malloc(sizeof(*stack));
stack->llist = malloc(sizeof(*stack->llist));
stack->llist->size = 0;
stack->llist->head = NULL;
return stack;

Note that I've also removed some unnecessary casts and parentheses, and changed the sizeof operator to calculate the memory you need based on the pointer you're storing into. 请注意,我还删除了一些不必要的强制转换和括号,并更改了sizeof运算符以根据要存储到其中的指针来计算所需的内存。

LListStack *initLListStack(void)
{
  LListStack *stack = (LListStack *) malloc(sizeof(LListStack)) ;
  stack->llist->size = 0; // **this is probably where it crashes**
  stack->llist->head = NULL;
  return(stack);
}

You allocate stack ok, but you do not allocate stack->llist . 您将stack分配为ok,但未分配stack->llist So stack->llist is uninitialized and then you dereference it in stack->llist->size . 因此stack->llist未初始化,然后在stack->llist->size取消引用它。 Dereferencing an uninitialized variable results in undefined behavior. 取消引用未初始化的变量将导致未定义的行为。

To fix this, allocate stack->list like this: 要解决此问题,请像下面这样分配stack-> list:

LListStack *initLListStack(void)
{
  LListStack *stack = (LListStack *) malloc(sizeof(LListStack)) ;
  stack->llist = (LListStack *) malloc(sizeof(LList1)) ; // ADD THIS LINE
  stack->llist->size = 0; 
  stack->llist->head = NULL;
  return(stack);
}

A segmentation fault error is usually caused by trying to dereference an uninitialized pointer. 分段错误错误通常是由于尝试取消引用未初始化的指针而引起的。 In your case, you have allocated memory for stack in your initLListStack method but you haven't initialized it -- in particular the llist field is not initialized to any particular value. 在您的情况下,您已经在initLListStack方法中为stack分配了内存,但尚未初始化它-特别是llist字段未初始化为任何特定值。 You need to allocate an LList1 and set the llist field to the newly-allocated memory. 您需要分配一个LList1并将llist字段设置为新分配的内存。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM