0

私は現在、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() を最初に実行しようとしているだけなので、まだ Main() にはあまりありません。スタックの初期化が問題のようです。

助けてくれてありがとう!

4

3 に答える 3

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 演算子を変更して、格納先のポインターに基づいて必要なメモリを計算することに注意してください。

于 2013-09-30T01:58:07.340 に答える
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);
}

OK を割り当てstackますが、割り当てませんstack->llist。そのstack->llistため、初期化されていないため、 で逆参照しstack->llist->sizeます。初期化されていない変数を逆参照すると、未定義の動作が発生します。

これを修正するには、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);
}
于 2013-09-30T01:49:32.297 に答える
0

通常、セグメンテーション フォールト エラーは、初期化されていないポインターを逆参照しようとすることによって発生します。あなたの場合、メソッドにメモリを割り当てましたがstackinitLListStack初期化していません。特に、llistフィールドは特定の値に初期化されていません。を割り当てて、新しく割り当てたメモリにフィールドをLList1設定する必要があります。llist

于 2013-09-30T01:52:45.223 に答える