我目前正在攻读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()中没有那么多,因为我只是想让它先运行。初始化堆栈似乎是问题所在。
感谢您的帮助!
答案 0 :(得分: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 :(得分:0)
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
,但不分配stack->llist
。因此stack->llist
未初始化,然后您在stack->llist->size
中取消引用它。解除引用
未初始化的变量会导致未定义的行为。
要解决此问题,请按以下方式分配stack-&gt;列表:
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);
}
答案 2 :(得分:0)
分段错误错误通常是由尝试取消引用未初始化的指针引起的。在您的情况下,您已在stack
方法中为initLListStack
分配了内存,但尚未对其进行初始化 - 特别是llist
字段未初始化为任何特定值。您需要分配LList1
并将llist
字段设置为新分配的内存。