【问题标题】:Segmentation Fault error - Implementing Stack using Linked lists分段错误错误 - 使用链表实现堆栈
【发布时间】:2013-10-05 18:58:50
【问题描述】:

我目前正在攻读 C 语言数据结构的大学课程,现在遇到了很多麻烦。我想明确一点,我寻求帮助的不是分数,只是练习挑战问题。

目标是使用链表实现堆栈。通过查看讲义,我认为我已经掌握了大部分功能。我需要演示 Push() 和 Pop() 将追加和假装。使用 Cygwin,我编译没有错误。但是当我尝试运行它时,我得到一个“分段错误”。这是什么意思,我该如何解决?如果我删除“stack = initLListStack();”,错误就会消失。这是我的代码:

#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);
}

我在 Main() 中还没有那么多,因为我只是想让它先运行。初始化堆栈似乎是个问题。

感谢你们的帮助!

【问题讨论】:

    标签: c data-structures linked-list stack


    【解决方案1】:

    问题出在您的initLListStack() 函数中:

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

    malloc 的结果是一个未初始化的内存块,大到足以容纳LListStack 结构。

    使用该内存做的第一件事就是读取它的llist 成员。由于这是未初始化的,因此您调用未定义的行为,幸运的是,这会导致段错误。 (发生这种情况时,编译器会在规范范围内向我们的讲师发送令人尴尬的电子邮件。)

    您需要先初始化llist,然后才能在堆栈中使用该成员。比如:

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

    请注意,我还删除了一些不必要的强制转换和括号,并更改了 sizeof 运算符以根据您存储的指针计算您需要的内存。

    【讨论】:

    • 非常感谢!那行得通。只是一个问题 1)我看到你在 malloc 之前取出了“(LListStack *)”。那有什么意义呢。我的教授一直告诉我们在 malloc 之前包含它,但我不确定它的作用,因为我一直在阅读的所有地方都没有这样做。
    • 你是教授显然生活在 C++ 中,或者如果你的程序设置不正确,你没有考虑 non-required 演员可以做的所有事情。标准 C 不需要从 void* 转换为任何其他指针类型。 Don't cast the result of malloc in standard C.
    【解决方案2】:

    分段错误错误通常是由试图取消引用未初始化的指针引起的。在您的情况下,您在 initLListStack 方法中为 stack 分配了内存,但您尚未对其进行初始化 - 特别是 llist 字段未初始化为任何特定值。您需要分配一个LList1 并将llist 字段设置为新分配的内存。

    【讨论】:

      【解决方案3】:
      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);
      }
      

      你分配stack ok,但你没有分配stack-&gt;llist。所以 stack-&gt;llist 未初始化,然后你在 stack-&gt;llist-&gt;size 中取消引用它。取消引用 未初始化的变量会导致未定义的行为。

      要解决这个问题,请像这样分配堆栈->列表:

      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);
      }
      

      【讨论】:

        猜你喜欢
        • 2013-10-05
        • 2021-01-17
        • 1970-01-01
        • 1970-01-01
        • 2012-06-10
        • 1970-01-01
        • 1970-01-01
        • 2021-12-03
        • 2021-08-04
        相关资源
        最近更新 更多