プログラムがバグっている箇所を教えて下さい(1)

このQ&Aのポイント
  • C++初心者です。以下のソースコードでバグっていると思われる箇所を教えていただけるとありがたいです。
  • int型整数を格納するスタックを、配列を用いて実現する(格納上限1000個)
  • C++のプログラムにバグがあり、修正が必要です。スタックのプッシュとポップの機能が正しく動かないようです。正常系テストと境界値テストを実行してバグの原因を特定してください。
回答を見る
  • ベストアンサー

プログラムがバグっている箇所を教えて下さい(1)

C++初心者です。 以下のソースコードでバグっていると思われる箇所を教えていただけるとありがたいです。 /* 02_LIFO.cpp * * int型整数を格納するスタックを、配列を用いて実現する(格納上限1000個) * */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include "02_LIFO.h" /* スタック格納要素最大数実装 */ const int LIFO::m_maxSize = 1000 * sizeof(int); /* コンストラクタ */ LIFO::LIFO() { memset(m_stack, 0, m_maxSize); } /* デストラクタ */ LIFO::~LIFO() { /* nop */ } /* プッシュ */ int LIFO::LIFO_push_array(const int push_value) { if (m_stored > m_maxSize) { return EXIT_FAILURE; } else { m_stack[m_stored++] = push_value; return EXIT_SUCCESS; } } /* ポップ */ int LIFO::LIFO_pop_array(int *pop_value) { if (m_stored == 0) { return EXIT_FAILURE; } else { *pop_value = m_stack[m_stored--]; return EXIT_SUCCESS; } } /* 以下テスト用 */ static void Check(bool result, int line) { if (result == false) { /* 結果がおかしい処理の行をログ出力 */ printf("ERROR Line:%d\n", line); } } /* 正常系テスト */ static void TestNormal(void) { int result; LIFO stack; result = stack.LIFO_push_array(10); Check((result == EXIT_SUCCESS), __LINE__); result = stack.LIFO_push_array(20); Check((result == EXIT_SUCCESS), __LINE__); int val = 0; result = stack.LIFO_pop_array(&val); Check((result == EXIT_SUCCESS), __LINE__); Check((val == 20), __LINE__); result = stack.LIFO_pop_array(&val); Check((result == EXIT_SUCCESS), __LINE__); Check((val == 10), __LINE__); } /* 境界値テスト */ static void TestLimit(void) { int result; LIFO stack; /* 空の状態でPOP */ int val = 0; result = stack.LIFO_pop_array(&val); Check((result == EXIT_FAILURE), __LINE__); /* MAX値までPUSH */ for (int i = 0; i < 1000; i++) { result = stack.LIFO_push_array(10); Check((result == EXIT_SUCCESS), __LINE__); } /* MAX値を超えてPUSH */ result = stack.LIFO_push_array(10); Check((result == EXIT_FAILURE), __LINE__); } /* メイン関数 */ int main() { /* テスト */ printf("TestStart\n"); TestNormal(); TestLimit(); printf("TestEnd\n"); return 0; }

noname#160888
noname#160888

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

  • ベストアンサー
  • wormhole
  • ベストアンサー率28% (1621/5657)
回答No.1

・int LIFO::m_maxSizeの扱い(m_stackに格納できる要素数とm_stackに確保されているバイト数が混同されてる) ・int LIFO::LIFO_push_array(const int push_value)とint LIFO::LIFO_pop_array(int *pop_value)の処理がかみ合ってない

noname#160888
質問者

お礼

なるほど…納得です。回答ありがとうございます^^

関連するQ&A

  • プログラムがバグっている箇所を教えて下さい(2)

    C++初心者です。 以下のソースコードでバグっていると思われる箇所を教えていただけるとありがたいです。 /* LIFO_04.cpp * * int型整数を格納するスタックを、配列を用いて実現する * メモリ確保処理回数を少なくするために、512*N個の格納時にメモリを確保する * */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include "LIFO_04.h" #define DEBUG #ifdef DEBUG static int newCount = 0; /* mallocのコール回数 */ static int resizeCount = 0; /* reallocのコール回数 */ static int deleteCount = 0; /* freeのコール回数 */ #endif LIFO_04::LIFO_04() : m_pStack(0), m_stored(0) { #ifdef DEBUG newCount = 0; resizeCount = 0; deleteCount = 0; #endif } LIFO_04::~LIFO_04() { /* nop */ } int LIFO_04::LIFO_push_array(const int push_value) { int result = PreProcess(); if (result == EXIT_SUCCESS) { m_pStack[m_stored++] = push_value; } return result; } int LIFO_04::LIFO_pop_array(int *pop_value) { int result; if (m_stored <= 0) { /* スタック空 */ result = EXIT_FAILURE; } else { *pop_value = m_pStack[--m_stored]; result = PostProcess(); } return result; } /* 指定バイト境界に値を切り上げる */ int LIFO_04::RoundUp(int val, int align) { if (val > 0) { return (((val - 1) / align) + 1) * align; } else { return val / align * align; } } /* 事前処理 */ int LIFO_04::PreProcess(void) { int result; if (m_stored == 0) { /* スタック新規作成 */ m_pStack = new int[m_blockLen]; #ifdef DEBUG newCount++; #endif } else if (m_stored % m_blockLen == 0) { /* スタック領域拡大 */ int resize = RoundUp(m_stored, m_blockLen * sizeof(int)); int* pBuf = ResizeBlock(m_pStack, resize); if (pBuf != 0) { m_pStack = pBuf; } } else { /* nop */ } return (m_pStack != 0) ? EXIT_SUCCESS : EXIT_FAILURE; } /* 事後処理 */ int LIFO_04::PostProcess(void) { int result; if (m_stored <= 0) { /* スタックが空になった */ delete m_pStack; #ifdef DEBUG deleteCount++; #endif m_pStack = 0; result = EXIT_SUCCESS; } else if (m_stored % m_blockLen == 0) { /* 領域縮小 */ int* pBuf = ResizeBlock(m_pStack, m_stored); if (pBuf != 0) { m_pStack = pBuf; result = EXIT_SUCCESS; } } else { result = EXIT_SUCCESS; } return result; } /* ブロックサイズを変更する */ int* LIFO_04::ResizeBlock(int* pBlock, int resize) { int* pBuf = new int[resize]; /*int* pBuf = (int*)(realloc(m_pStack, sizeof(int) * resize));*/ #ifdef DEBUG resizeCount++; #endif if (pBuf != 0) { /* 新たに確保したメモリへコピーして、元の領域を開放 */ memcpy(pBuf, pBlock, resize); delete pBlock; } return pBuf; } /* 以下評価用 */ #ifdef DEBUG static void Check(bool result, int line) { if (result == false) { printf("ERROR Line:%d\n", line); } } static void TestNormal(void) { int result; LIFO_04 stack; result = stack.LIFO_push_array(10); Check((result == EXIT_SUCCESS), __LINE__); Check((newCount == 1), __LINE__); result = stack.LIFO_push_array(20); Check((result == EXIT_SUCCESS), __LINE__); int val = 0; result = stack.LIFO_pop_array(&val); Check((result == EXIT_SUCCESS), __LINE__); Check((val == 20), __LINE__); result = stack.LIFO_pop_array(&val); Check((result == EXIT_SUCCESS), __LINE__); Check((val == 10), __LINE__); Check((deleteCount == 1), __LINE__); Check((resizeCount == 0), __LINE__); } static void TestLimit(void) { int result; LIFO_04 stack; /* 空の状態でPOP */ int val = 0; result = stack.LIFO_pop_array(&val); Check((result == EXIT_FAILURE), __LINE__); /* m_blockLen値までPUSH */ for (int i = 0; i < 512; i++) { result = stack.LIFO_push_array(10 + i); Check((result == EXIT_SUCCESS), __LINE__); } Check((deleteCount == 0), __LINE__); Check((resizeCount == 0), __LINE__); /* m_blockLen値を超えてPUSH */ result = stack.LIFO_push_array(20); Check((result == EXIT_SUCCESS), __LINE__); Check((resizeCount == 1), __LINE__); result = stack.LIFO_pop_array(&val); Check((result == EXIT_SUCCESS), __LINE__); Check((val == 20), __LINE__); result = stack.LIFO_pop_array(&val); Check((result == EXIT_SUCCESS), __LINE__); Check((val == 10 + 511), __LINE__); } #endif int main() { #ifdef DEBUG printf("TestStart\n"); TestNormal(); TestLimit(); printf("TestEnd\n"); #endif return 0; }

  • スタックの配列プログラム

    スタックを配列で実現するプログラムとして #include<stdio.h> #define stack_size 100 #define stack_el_type int stack_el_type stack[stack_size]; int sp; void init_stack() { sp=-1 } void push(stack_el_type x) { if (sp < stack_size -1) stack[++sp] = x; else{ printf("stack full error.\n"); exit(1); } } stack_el_type pop() { if(sp >= 0 ) return stack[sp--]; else { printf("stack empty error.\n") exit(1); } } 上の完成形を参照として、 他の作り方として int stack[100] int sp void push(int x) int pop() を用いて作成する場合どのようにすればよいのでしょうか? またスタックを一方向リストで実現するプログラムを作成するとき struct node{ int data; struct node *next; } struct node *push(int x,struct node *root) struct node *pop(struct node *root) を用いて作成する場合どのようにすればよいのでしょうか? よろしければご教授お願いします

  • C言語で変更していただきたい所があるのですが・・・

    下のソースを加減乗除だけでなく、余りを求める演算(%)やべき乗演算(^)も使えるようにしたいのですがうまくいきません。 どなたか変更例をお見せできますでしょうか? #include <stdio.h> #include <stdlib.h> #define STACK_MAX 10 /* 配列によるスタック構造 */ double stack[STACK_MAX]; /* スタック頂上の位置(最下部からのオフセット)*/ int stack_top = 0; /* スタックへのpush */ void stack_push(double val) { if(stack_top == STACK_MAX) { /* スタックが満杯になっている */ printf("エラー:スタックが満杯です(Stack overflow)\n"); exit(EXIT_FAILURE); } else { /* 渡された値をスタックに積む */ stack[stack_top] = val; stack_top++; } } /* スタックからpop */ double stack_pop(void) { if(stack_top == 0) { /* スタックには何もない */ printf("エラー:スタックが空なのにpopが呼ばれました" "(Stack underflow)\n"); exit(EXIT_FAILURE); return 0; } else { /* いちばん上の値を返す */ stack_top--; return stack[stack_top]; } } int main(void) { char buffer[256]; double cal1, cal2; int i; do { printf("現在のスタック(%d個):", stack_top); for(i = 0; i < stack_top; i++) { printf("%0.3f ", stack[i]); } printf("\n>"); fgets(buffer, 255, stdin); switch(buffer[0]) { case '+': cal1 = stack_pop(); cal2 = stack_pop(); stack_push(cal2 + cal1); break; case '-': cal1 = stack_pop(); cal2 = stack_pop(); stack_push(cal2 - cal1); break; case '*': cal1 = stack_pop(); cal2 = stack_pop(); stack_push(cal2 * cal1); break; case '/': cal1 = stack_pop(); cal2 = stack_pop(); stack_push(cal2 / cal1); break; case '=': /* =の場合はこのすぐあとでwhile文からも抜ける */ break; default: /* 入力された値は数字のはずなので,スタックに積む */ stack_push(atoi(buffer)); break; } } while(buffer[0] != '='); printf("計算結果は%f です。\n",stack_pop()); if(stack_top != 0) { printf("エラー:スタックにまだ数が残っています\n"); return EXIT_FAILURE; } return EXIT_SUCCESS; }

  • スタックで成績表を作るプログラム。

    成績表を作りたい。Studentのクラスを要素とするクラスStackを完成させてプログラムが動作するようにせよという問題なのですがprivateの物をどうやって要素にすればよいのでしょうか? class Student { private int id; private String name; private int eng; private int math; private int kokugo; Student(int i,String nm,int e,int m,int k) { id=i;name=nm;eng=e;math=m;kokugo=k; } void show(){ System.out.println("("+id+","+name+","+ eng+","+ math+","+ kokugo+")"); } } class Stack { } class Sample { public static void main(String[] args) { Stack ss=new Stack(3); ss.push(new Student(1,"A",10,10,10)); ss.push(new Student(2,"B",20,10,10)); ss.push(new Student(3,"C",30,10,10)); ss.push(new Student(4,"D",40,10,10)); ss.pop(); ss.pop(); ss.pop(); ss.pop(); } }

    • ベストアンサー
    • Java
  • スタックについて

    スタックを実現するプログラムを作っているのですが、実行するとセグメテーション違反が表示されます。でもどこが間違っているのかわかりません!どうしたらいいのでしょう? #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); } }

  • スタックのデータ構造を作りたい

    C言語でスタックと、スタックにデータを入れるプッシュ、取り出すポップを作りたいと思っており そこで以下のようなものを作ってみました。 ********************************************** #include<stdio.h> typedef struct{ int a[100]; int head=0; }Stack; void push(Stack stc,int x){ stc.a[head]=x; stc.head++; } int pop(Stack stc){ return(stc.a[head-1]); stc.head--; } int main void{ int j; Stack s; push(s,5); push(s,90); j=pop(s); printf("%d",j); j=pop(s); printf("%d",j); return 0; } ****************************** コンパイルするとエラーが出まくりです。 何をどう直せばよいのか、どこが変なのかご教授いただきたいです。 よろしくお願いいたします。

  • このプログラムが実行できません。

    スタックの動きを再現するプログラムを作ったのですが、エラーがでます。プログラムは以下に示します。 メインクラス public class mainStack { public static void main(String[] args) { StackTest stack=new StackTest(); stack.push("AAAAA"); stack.push("BBBBB"); } } スタックのクラス import java.util.ArrayList; @SuppressWarnings("unchecked") public class StackTest implements Stack { ArrayList list=new ArrayList(); public int AA=0; public boolean empty() { if(list.isEmpty()==true){ return true; } else{ return false; } } public void pop() { list.remove(AA); AA--; } public void push(String element) { list.add(element); AA++; } public void top(){ System.out.println(list.get(AA)); } } 何故かlist.add()のところにエラーが出てしまいます。是非分かる方解答お願いします。

    • ベストアンサー
    • Java
  • コンパイルできるのですが実行途中でエラーが

    #include<iostream> #include<cstdlib> using namespace std; class stack{ char *stck; int tos; int size; public: stack(char c); void push(char ch); char *pop(); ~stack(); }; stack::stack(char c){ tos=0; stck=(char*)malloc(c); size=c; cout<<"生成スタック\n"; if(!stck){ cout<<"メモリ割り当てエラー\n"; exit(1); } } void stack::push(char ch){ if(tos==size){ cout<<"スタックは一杯です\n"; return; } *stck=ch; stck++; tos++; } char *stack::pop(){ if(tos==0){ cout<<"スタックは空です\n"; return 0; } stck--; tos--; return stck; } stack::~stack(){ free(stck); } int main(){ stack s1(10),s2(10); int i; char *o; s1.push('a'); s2.push('x'); s1.push('b'); s2.push('y'); s1.push('c'); s2.push('z'); for(i=0;i<5;i++){ o=s1.pop(); cout<<"s1をポップする"<<*o<<"\n"; } for(i=0;i<5;i++){ o=s2.pop(); cout<<"s2をポップする"<<*o<<"\n"; } return 0; } なんですが、実行した所 生成スタック 生成スタック s1をポップするc s1をポップするb s1をポップするa スタックは空です までで止まってしまいます。 たぶんreturn 0の戻り値の型がポインタだから止まってしまうのだろうと思います。 正しく実行するにはどうすればいいのでしょうか? お願いします。

  • クラス→スタックを使う

    初歩的なとこですがすでに着いていけず困っています。 問題は、  下記のプログラムにおいて、スタックへ整数10を入れるには、push(10)としてメソッドpushを呼び出す。逆に、スタックから値を取り出すには、pop()メソッドを呼び出す。また、現在のスタックの先頭位置(スタックポインタsp)は、メソッドgetSP()を呼び出すことで得られる。今、整数10と20をこの順にスタックへ入れた後、スタックから先頭の要素(整数)を取り出す。ただし、取り出した値は出力する必要はない。そして、これらの操作(3回ある)が終わる毎に、その時のスタックポインタspの値を出力する。  このような動作をするようにmainメソッドを完成させ、実行結果を確かめなさい。 class Stack { int [] stack = new int[10]; int sp = 0; void push(int n){ if(sp < stack.length){ stack[sp] = n; sp++; } } void pop(){ if(sp > 0)sp--; } int getSp(){ return sp; } public static void main(String[] args){ // <この部分を完成させなさい> } } 宜しくお願いします!!  

    • ベストアンサー
    • Java
  • 再帰呼び出しについて

    これらの関数をうまく結びつけるにはどうしたらよいのでしょうか? Tree *henkan(void) { int suu; int yusen; suu=next(); yusen=check_yusen(suu); if(yusen==-1) return; if(yusen==1) check_1(suu); else if(yusen==2) check_2(suu); else if(yusen==3) check_3(suu); } void check_1(char suu) { Tree *n1; suu=toint(suu); suu=check_suu(suu); n1=make_node(suu,0,0); push(n1); henkan(); } void check_2(char suu) { Tree *n1; Tree *n2; henkan(); n2=pop(); n1=pop(); result=make_node(suu,n1,n2); push(result); } void check_3(char suu) { Tree *n1; Tree *n2; int num; n1=pop(); num=next(); num=toint(num); num=check_suu(num); n2=make_node(num,0,0); result=make_node(suu,n1,n2); push(result); henkan(); } int check_suu(int suu) { int check; int num; num=next(); check=check_yusen(num); if(check==1) { num=toint(num); suu=10*suu+num; suu=check_suu(suu); return suu; } else if(check==-1) return suu; else { sikip--; return suu; } }

専門家に質問してみよう