Stack corruption

Hi,

I'm writing a program with binary tree. The program runs perfectly ok, no syntax errors, no logical error, but when it terminates, i got this error msg
"Run - Time Check Failure #2 - stack around the variable 'myTree' was corrupted".
Can anyone pls tell me what happened?

Thanks.
stack corruption is usually caused by you stepping out of bound in an array somewhere.

Since it's stack corruption and not heap corruption, this means you're likely stepping out of bounds in an array that's allocated on the stack (local to a specific function)

Since stack corruption is usually detected when a function exits, that means the culprit is likely in whetever function is running when the program gives you that message. Since you say you get it when the program closes, that tells me that main() is the function with the problem.


Post your main() in here so we can see it. Maybe we'll be able to spot the problem.
Here's the main function.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

int main()
{
	
int main()
{
	system("color 27");
	bool cont;
	ATM myATM = ATM();

	do
	{
		system("cls");
		myATM.printGreeting();
		Sleep(2500);
		system("cls");	
		cont = myATM.getUserNPass();
		if (!cont)
			Sleep(3000);
	}
	while (!cont);

	myATM.printMainMenu();
	
	system("pause");

	return 0;
}
}


And here's the header file for ATM class:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

class ATM
{
	ifstream inputFile;
	ofstream outputFile;

	BinaryTree records;
	TreeNode *currentRecord;
	//...
	void greeting();
public:
	ATM();
	~ATM();
	void printGreeting();
	void printTitle();
	bool getUserNPass();
	void printMainMenu();
	
};


Thank you
Last edited on
Ack. Well since myATM is on the stack, the problem could be anywhere in ATM.

I'd need to see the full cpp file for the ATM class.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
#include "ATM.h"
#include <ctime>
#include <Windows.h>
#include <iostream>
#include <conio.h>
#include <fstream>
#include <Windows.h>
using namespace std;

ATM::ATM()
{
	loadRecords();
	currentRecord = NULL;
	timesTry = timesU = timesP = 0;
	for (int n = 0; n <= 5; n++)
		user[n] = pass[n] = 0;
	user[6] = user[7] = user[8] = 0;
}

ATM::~ATM()
{
}


bool ATM::getUserNPass()
{
	HANDLE colors = GetStdHandle(STD_OUTPUT_HANDLE);

	printTitle();
	printLoginScreen();
	int times = 0;

	//*************getID***************
	do
	{
		gotoxy(40, 24);
		SetConsoleTextAttribute(colors,	BACKGROUND_RED | BACKGROUND_BLUE | BACKGROUND_GREEN);
		getInput(user, 8);
	
	
		//****************getPIN***********
		gotoxy(40, 28);
		SetConsoleTextAttribute(colors,	BACKGROUND_RED | BACKGROUND_BLUE | BACKGROUND_GREEN);
		getInput(pass,4);

		//*******Check ID and PIN ******
		currentRecord = records.searchNode(user,pass);
		times++;

			
		if (currentRecord == NULL && times <= 2)
		{	
			gotoxy(20, 31);
			SetConsoleTextAttribute(colors,	BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_INTENSITY | FOREGROUND_RED);		
			cout << "The ID or PIN you entered is incorrect";
			SetConsoleTextAttribute(colors,	BACKGROUND_RED | BACKGROUND_BLUE | BACKGROUND_GREEN);
			gotoxy(40,28);
			cout << "    \b\b\b\b";
			gotoxy(40, 24);
			cout << "        \b\b\b\b\b\b\b\b";
		}
	}
	while (times <3 && currentRecord == NULL);

	if (!currentRecord)
	{
		printAlertMsg();
		cout << "entered U = " << user << endl;
		cout << "entered P = " << pass << endl;
		return false;
	}
	
	return true;
}

void ATM::getInput(char input[], int length)
{
	int n = 0;
	char currentK;
	
	do
	{
		currentK = getch();
		if (n == length && currentK == '\b')
		{
			n--;
			cout << "\b \b";
			continue;
		} 
		if (n < 0)
		{
			n = 0;
			continue;
		}
		
		if (n == 0 && currentK == '\b')
			continue;
		if (n < length && n >= 0)
		{
			
			if (currentK == '\b')
			{
				input[n--] = 0;
				cout << "\b \b";
			}
			else 
			{
				cout << "*";
			    input[n++] = currentK;
			}
		}
	}
	while (currentK != '\r');
}

void ATM::generateRecords()
{
	ofstream oFile("master1.txt");
	if (!oFile)
	{
		cout << "ERROR opening file to write" << endl;
		exit(0);
	}

	oFile << "H4302984\t" << "7876\t" << "REARDON\t" << "JOSEPH\t" << "43295430\t" << "500\t" << "59483729\t" << "450\n";
	oFile << "X4303956\t" << "8904\t" << "ADAMS\t" << "DONALD\t" << "43949435\t" << "700\t" << "43243984\t" << "6000\n";
	oFile << "G4830234\t" << "5930\t" << "ANDREW\t" << "TUFTS\t" << "98038904\t" << "1200\t" << "11203909\t" << "5940\n";
	oFile << "B2320090\t" << "1098\t" << "ALBERT\t" << "EISTEIN\t" << "60985032\t" << "700\t" << "89093876\t" << "700\n";
	oFile << "L0493056\t" << "1010\t" << "HANLEY\t" << "HAMILTON\t" << "90392435\t" << "2000\t" << "88445569\t" << "1000\n";
	oFile << "Y8394839\t" << "8989\t" << "THOMAS\t" << "JEFFERSON\t" << "49039283\t" << "7000\t" << "92939495\t" << "9000\n";
	oFile << "C1236785\t" << "4455\t" << "ANDREW\t" << "JACKSON\t" << "83025405\t" << "1230\t" << "45930983\t" << "560\n";
	oFile << "P9204930\t" << "9920\t" << "JOHN\t" << "ADAMS\t" << "50493045\t" << "560\t" << "33949020\t" << "700\n";
	oFile << "T5004532\t" << "6940\t" << "KAYLA\t" << "LEE\t" << "30293049\t" << "9060\t" << "29204958\t" << "1030\n";
	oFile << "A1234567\t" << "9090\t" << "EMILY\t" << "WATTS\t" << "10985936\t" << " 300\t" << "45639852\t" << "2000\n";
	
	oFile.close();
}

void ATM::loadRecords()
{
	//Temporary -> del later
	generateRecords();

	//choose input file
	setInputFile();

	
	for (int n = 0; n < 10; n++)
	{
		Data temp;
		inputFile >> temp.ID;
		inputFile >> temp.PIN;
		inputFile >> temp.first;
		inputFile >> temp.last;
		inputFile >> temp.checkNo;
		inputFile >> temp.checkBal;
		inputFile >> temp.saveNo;
		inputFile >> temp.saveBal;
		records.insertNode(temp);
	}	
}

void ATM::setInputFile()
{
     //...
	inputFile.open("master1.txt");
}

The original source code is too long to be posted here (1100 lines), so I've deleted some functions that i'm sure can't cause the error.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
int main()
{
	
int main()
{
	system("color 27");
	bool cont;
	ATM myATM = ATM();

	do
	{
		system("cls");
		myATM.printGreeting();
		Sleep(2500);
		system("cls");	
		cont = myATM.getUserNPass();
		if (!cont)
			Sleep(3000);
	}
	while (!cont);

	myATM.printMainMenu();
	
	system("pause");

	return 0;
}
}


Is it just an error when you copied the code to the forums, or do you really have two main functions?
@archaic,
... and is one of them nested within the other one?

Lol I doubt it; that wouldn't compile.

@Disch,
Given that the stack corruption occurs at the end of the program, wouldn't that imply the destructor was at fault? If you had a buffer overflow or an off-by-one error then surely the program would crash when that overflow or error occurred. So the corruption likely occurs when the destructor is called. But his destructor is empty which is confusing.

Edit: misread code.
Last edited on
oops! sorry. it's an error when copying the code. Just one main.
This is all suspect:

1
2
3
4
5
6
7
8
9
ATM::ATM()
{
	loadRecords();
	currentRecord = NULL;
	timesTry = timesU = timesP = 0;
	for (int n = 0; n <= 5; n++)
		user[n] = pass[n] = 0;
	user[6] = user[7] = user[8] = 0;
}


how large are user and pass? I don't even see them defined anywhere.

Given that the stack corruption occurs at the end of the program, wouldn't that imply the destructor was at fault?


No.

The corruption occurs much earlier (pretty much anywhere in your program is suspect). The program is just telling you about it at the end of the function because that's when it unwinds the stack and can actually look for the corruption.
Last edited on
Oh, fair enough.

1
2
char user[9];
char pass[5];
That's probably why then. It's an off-by-one error -- the loop that Disch indicated is iterating one too many times. Change the "<=" to "<" (if it's <= then you're trying to dereference pass[5] which doesn't exist (remember that arrays count from 0, so the last element in pass is pass[4])).
aaahhhhh!!!!! can't believe i made that stupid mistake!!!!!!!!!!!!!!!!!!!!
thanks!!
Did it work?
yes!!!! ^^
Topic archived. No new replies allowed.