• ベストアンサー

スタックについて

スタックを実現するプログラムを作っているのですが、実行するとセグメテーション違反が表示されます。でもどこが間違っているのかわかりません!どうしたらいいのでしょう? #include<stdio.h> #include<stdlib.h> struct stack{ int max; int used; int *array; }; struct stack * stack_create(int n) { struct stack *s; int i; s->array=(int *)malloc(sizeof(int)*n); s->used=0; s->max=n; return 0; } void stack_free(struct stack *s) { free(s); } int stack_push(struct stack *s,int datum) { if(s->used>=s->max){ return 0; } s->array[s->used]=datum; s->used++; return 1; } int stack_pop(struct stack *s,int *datump) { if(s->used<=0){ return 0; } *datump=s->array[s->used-1]; s->used--; return 1; } int stack_is_empty(const struct stack *s) { return s->used==0; } int main() { struct stack s; int i,p; int n; scanf("%d",&n); stack_create(n); for(i=0;i<=5;i++){ stack_push(&s,i); printf("push%2d\n",i); } for(i=1;i<=3;i++){ stack_pop(&s,&p); printf("pop%2d\n",p); } }

質問者が選んだベストアンサー

  • ベストアンサー
  • Oh-Orange
  • ベストアンサー率63% (854/1345)
回答No.5

★アドバイス (1)stack_create  構造体『struct stack』の領域を確保していない。  ポインタ『s』には構造体『struct stack』の領域のポインタをセットしていない。  戻り値に 0 を返しているので確保した領域は忘れる。→完璧なメモリリーク (2)stack_free  構造体『struct stack』の『array』を解放してから『s』を解放しないとまずい。  free の操作は2段階になる。確保もmallocを2段階する仕様なので当然です。 (3)stack_push  問題なし。 (4)stack_pop  問題なし。 (5)stack_is_empty  問題なし。 (6)main  戻り値が int なのにリターンしていない。記述すること。  構造体『struct stack』はポインタで宣言すること。  そのポインタ『s』に stack_create 関数の戻り値を代入すること。  『s』はポインタなので『stack_push(s,i);』となる。  『s』はポインタなので『stack_pop(s,&p);』となる。 ・以上。上記のを参考に問題点を修正して下さい。

その他の回答 (4)

  • aris-wiz
  • ベストアンサー率38% (96/252)
回答No.4

既に回答がでてますが、 別アプローチです。 struct stack * stack_create(int n) {  struct stack *s;  int i;  s = (struct stack *)malloc(sizeof(struct stack));  if ( !s )   return NULL;  s->array=(int *)malloc(sizeof(int)*n);  if ( !s->array ){   free( );   return NULL;  }  s->used=0;  s->max=n;  return s; } void stack_free(struct stack *s) {  if ( !s ){   if ( s->array ){    free( s->array );    s->array = NULL;   }   free(s);  } } 使う側では int main() {  struct stack *s;  s = stack_create(10);  stack_push( s, 1 );  stack_pop( s, &p );  stack_free(s);  return 0; } >ANo.3 スタックというのはLIFOまたはFILOどちらの 実装を取っていてもOKです。 データを取り出す際、最後に入れたものから順に 取り出すことが出来ればそのデータ構造はスタックです。

  • ency
  • ベストアンサー率39% (93/238)
回答No.3

細かい話になってしまいますが、スタックって通常、下から順番にデータを積み上げていきませんか? つまり、配列の末尾から先頭に向けてデータを積み上げていくと。。。 で、取り出すときは、現在データがある先頭の箇所 (=スタックポインタ) から末尾に向けてデータを取り出していくと。。。 ま、先頭からデータを入れていって、現在データがある末尾の箇所から先頭に向けてデータを取り出していくという方法でも、向きが逆なだけでいっしょといえばいっしょか。。。 ちょっと気になったもので。。。

  • chie65536
  • ベストアンサー率41% (2512/6032)
回答No.2

#include<stdio.h> #include<stdlib.h> struct stack{  int max;  int used;  int *array; }; void stack_create(struct stack *s,int n) {  int i;  s->array=(int *)malloc(sizeof(int)*n);  s->used=0;  s->max=n;  return; } void stack_free(struct stack *s) {  free(s->array); } int stack_push(struct stack *s,int datum) {  if(s->used>=s->max){   return 0;  }  s->array[s->used]=datum;  s->used++;  return 1; } int stack_pop(struct stack *s,int *datump) {  if(s->used<=0){   return 0;  }  *datump=s->array[--(s->used)];  return 1; } int stack_is_empty(const struct stack *s) {  return !s->used; } int main() {  struct stack s;  int i,p;  int n;  scanf("%d",&n);  stack_create(&s,n);  for(i=0;i<=5;i++){   stack_push(&s,i);   printf("push%2d\n",i);  }  for(i=1;i<=3;i++){   stack_pop(&s,&p);   printf("pop%2d\n",p);  } }

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.1

stack_create の中の s が, 初期化されていないのに s->array = ... などと使われていますね. さらに, この s を初期化しても main の中で s.array などが初期化されていないので問題になります. そもそも stack_create の中の s と main の中の s は完全に無関係ですよ. stack_create の返り値の意味もわからんけど, とりあえず今はほかっておく.

関連するQ&A