재귀 함수가있는 클래스가 있습니다. 나는 100 건을 테스트했고 코드는 잘 작동한다. 그러나 다른 테스트를 실행하고 몇 번의 재귀 호출 후에 스택 오버플로를 보여주는 First-Inception 예외를 받았다.이를 무시하고 메모리 읽기 위반에 대한 처리되지 않은 예외를 표시했다.재귀 함수를 사용하는 동안 C++ 스택 오버플로
내가 (종료 조건을 가지고하지 실제 코드) 다음 코드가 있다고 가정 : 나는 디버거를 사용할 때
class Foo {
void Bar() {
Bar();
};
};
, 나는 시간에 Bar
라는 것을 알게을의 this
포인터가받는 잘못된 주소 번호로 인해 Foo
개체가 잘못 읽혀졌고 그 이유를 모르겠습니다.
누구에 대해 알고 있나요?
또는 시도해야합니까?
class Foo {
static void Bar (Foo* obj) {
Foo::Bar(obj);
};
};
편집 여기
게임 보석을 시뮬레이션하는 데 사용되는 실제 코드입니다. 나는 scanTile
방법
enum MOVE {MOVE_T, MOVE_L, MOVE_R, MOVE_B}; // Move Direction
enum SCORE {SCORE_3 = 1, SCORE_4 = 2, SCORE_5 = 4}; // Score Types
enum ERROR {ERR_DROP = 1, ERR_COUNT, ERR_MOVE}; // User-defined Error Code
class Jewel {
private:
UINT32 m, n, score, x, y;
char** map;
bool** scanned;
char move;
void init() {
map = new char*[n];
scanned = new bool*[n];
for (UINT32 i = 0; i < n; i++) {
map[i] = new char[m];
scanned[i] = new bool[n];
};
};
void reinit() {
for (UINT32 i = 0; i < n; i++)
for (UINT32 j = 0; j < n; j++)
scanned[i][j] = false;
};
void uninit() {
for (UINT32 i = 0; i < n; i++) {
delete[m] map[i];
delete[n] scanned[i];
};
delete[n] map;
delete[n] scanned;
};
void fileInput() {
std::ifstream fInput("input.txt");
fInput >> n >> m;
init();
for (UINT32 j = 0; j < m; j++)
for (UINT32 i = 0; i < n; i++)
fInput >> map[i][j];
fInput.close();
};
void fileOutput() {
std::ofstream fOutput("output.txt");
fOutput << score << '\n';
for (UINT32 j = 0; j < n; j++) {
for (UINT32 i = 0; i < n; i++)
fOutput << map[i][n - 1 - j] << ' ';
fOutput << '\n';
};
fOutput.close();
uninit();
};
bool inputMove() {
std::cin >> x >> y >> move;
if ((x == -1) && (y == -1) && (move == 'A'))
return false;
else
return true;
};
void outputMove() {
std::cout << '\n' << score << '\n';
for (UINT32 j = 0; j < n; j++) {
for (UINT32 i = 0; i < n; i++) {
std::cout << map[i][n - 1 - j] << ' ';
};
std::cout << '\n';
};
};
void swap(char &a, char &b) {
char temp = a;
a = b;
b = temp;
};
bool beginMove() {
switch (move) {
case 'T':
if (x < n - 1) {
swap(map[y][x], map[y][x + 1]);
return true;
};
break;
case 'B':
if (0 < x) {
swap(map[y][x], map[y][x - 1]);
return true;
};
break;
case 'L':
if (0 < y) {
swap(map[y][x], map[y - 1][x]);
return true;
};
break;
case 'R':
if (y < n - 1) {
swap(map[y][x], map[y + 1][x]);
return true;
};
break;
};
return false;
};
void revertMove() {
switch (move) {
case 'T':
swap(map[y][x], map[y][x + 1]);
break;
case 'B':
swap(map[y][x], map[y][x - 1]);
break;
case 'L':
swap(map[y][x], map[y - 1][x]);
break;
case 'R':
swap(map[y][x], map[y + 1][x]);
break;
};
};
void drop() {
for (UINT32 i = 0; i < n; i++) {
UINT32 j = 0;
while (j < n && map[i][j])
j++;
if (j < n) {
UINT32 k = j + 1;
while (j < n)
if (!map[i][j]) {
while ((k < m) && !map[i][k])
k++;
if (!map[i][k])
exit(ERR_DROP);
map[i][j] = map[i][k];
map[i][k] = 0;
j++;
k++;
};
};
};
};
bool scanMap() {
reinit();
UINT32 sessionScore = 0;
for (UINT32 j = 0; j < n; j++)
for (UINT32 i = 0; i < n; i++)
if (!scanned[i][j])
sessionScore += startScan(i, j);
if (sessionScore) {
score += sessionScore;
return true;
} else
return false;
};
UINT32 startScan(const UINT32 &col, const UINT32 &row) {
UINT32 count = 1;
scanned[col][row] = true;
if ((row < n - 1) && !scanned[col][row + 1] && (map[col][row] == map[col][row + 1]))
count += scanTile(col, row + 1, MOVE_T, (0 < row) && (map[col][row] == map[col][row - 1]));
if ((0 < row) && !scanned[col][row - 1] && (map[col][row] == map[col][row - 1]))
count += scanTile(col, row - 1, MOVE_B, (row < n - 1) && (map[col][row] == map[col][row + 1]));
if ((col < n - 1) && !scanned[col + 1][row] && (map[col][row] == map[col + 1][row]))
count += scanTile(col + 1, row, MOVE_R, (0 < col) && (map[col][row] == map[col - 1][row]));
if ((0 < col) && !scanned[col - 1][row] && (map[col][row] == map[col - 1][row]))
count += scanTile(col - 1, row, MOVE_L, (col < n - 1) && (map[col][row] == map[col + 1][row]));
if ((count < 3) && (count != 1))
exit(ERR_COUNT);
if (count >= 3)
map[col][row] = 0;
if (count == 1)
return 0;
else if (count == 3)
return count*SCORE_3;
else if (count == 4)
return count*SCORE_4;
else if (count >= 5)
return count*SCORE_5;
};
UINT32 scanTile(const UINT32 &col, const UINT32 &row, const MOVE &direction, const bool &opposite = false) {
UINT32 count = 1;
UINT32 temp = 0;
bool counted = false;
switch (direction) {
case MOVE_T:
if ((row < n - 1) && (map[col][row] == map[col][row + 1]))
if (scanned[col][row + 1])
counted = true;
else
count += scanTile(col, row + 1, MOVE_T, (0 < row) && (map[col][row] == map[col][row - 1]));
break;
case MOVE_B:
if ((0 < row) && (map[col][row] == map[col][row - 1]))
if (scanned[col][row - 1])
counted = true;
else
count += scanTile(col, row - 1, MOVE_B, (row < n - 1) && (map[col][row] == map[col][row + 1]));
break;
case MOVE_R:
if ((col < n - 1) && (map[col][row] == map[col + 1][row]))
if (scanned[col + 1][row])
counted = true;
else
count += scanTile(col + 1, row, MOVE_R, (0 < col) && (map[col][row] == map[col - 1][row]));
break;
case MOVE_L:
if ((0 < col) && (map[col][row] == map[col - 1][row]))
if (scanned[col - 1][row])
counted = true;
else
count += scanTile(col - 1, row, MOVE_L, (col < n - 1) && (map[col][row] == map[col + 1][row]));
break;
default:
exit(ERR_MOVE);
};
if ((opposite ? 1 : 0) + 1 + count + (counted ? 1 : 0) >= 3) {
switch (direction) {
case MOVE_T:
case MOVE_B:
temp = 0;
if ((col < n - 1) && !scanned[col + 1][row] && (map[col][row] == map[col + 1][row]))
count += temp = scanTile(col + 1, row, MOVE_R, (0 < col) && (map[col][row] == map[col - 1][row]));
if ((0 < col) && !scanned[col - 1][row] && (map[col][row] == map[col - 1][row]))
count += scanTile(col - 1, row, MOVE_L, temp ? true : false);
break;
case MOVE_L:
case MOVE_R:
temp = 0;
if ((row < n - 1) && !scanned[col][row + 1] && (map[col][row] == map[col][row + 1]))
count += temp = scanTile(col, row + 1, MOVE_T, (0 < row) && (map[col][row] == map[col][row - 1]));
if ((0 < row) && !scanned[col][row - 1] && (map[col][row] == map[col][row - 1]))
count += scanTile(col, row - 1, MOVE_B, temp ? true : false);
break;
default:
exit(ERR_MOVE);
};
scanned[col][row] = true;
map[col][row] = 0;
return count;
} else {
return 0;
};
};
public:
Jewel() : score(0) {
fileInput();
};
void process() {
outputMove();
while (inputMove()) {
if (beginMove()) {
bool first = true;
while (scanMap()) {
outputMove();
drop();
outputMove();
first = false;
};
if (first)
revertMove();
};
outputMove();
};
fileOutput();
};
};
음, 이것은 밑바닥이 아닌 재귀입니까? 아니면 실제 코드가 아닐까요? –
실제 코드는 매우 복잡합니다 –
4 월 바보는 결코 복잡하지 않습니다 – sehe