プログラムがバグっている箇所を教えて下さい(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;
}
お礼
ありがとうございました! 的確な回答ありがとうございます。 とてもすっきりしました。 ありがとうございました!