- ベストアンサー
スタックについて
スタックを実現するプログラムを作っているのですが、実行するとセグメテーション違反が表示されます。でもどこが間違っているのかわかりません!どうしたらいいのでしょう? #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); } }
- みんなの回答 (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)
既に回答がでてますが、 別アプローチです。 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)
細かい話になってしまいますが、スタックって通常、下から順番にデータを積み上げていきませんか? つまり、配列の末尾から先頭に向けてデータを積み上げていくと。。。 で、取り出すときは、現在データがある先頭の箇所 (=スタックポインタ) から末尾に向けてデータを取り出していくと。。。 ま、先頭からデータを入れていって、現在データがある末尾の箇所から先頭に向けてデータを取り出していくという方法でも、向きが逆なだけでいっしょといえばいっしょか。。。 ちょっと気になったもので。。。
- chie65536
- ベストアンサー率41% (2512/6032)
#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)
stack_create の中の s が, 初期化されていないのに s->array = ... などと使われていますね. さらに, この s を初期化しても main の中で s.array などが初期化されていないので問題になります. そもそも stack_create の中の s と main の中の s は完全に無関係ですよ. stack_create の返り値の意味もわからんけど, とりあえず今はほかっておく.