Mysterious Memory Leak

Hi all,

I have a simple program that creates a histogram of student grades for an assignment. However, when I run the program in a debugger, using Microsoft Visual C++ 2010 Express, it states that there is a memory leak. So I commented the lines that had nothing to do with using any dynamic memory and still yet there is a leak. Is it possible that this could be a bug in the IDE that I am using or is this error on my part. My code is as follows. Thank you for any and all help.

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
170
171
172
#include <iostream>
#include <string>
#include <vector>
#include <cstdlib>
#include <iomanip>

#define CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>

using namespace std;

//Function Prototypes
//================================================================
bool finished();
//Preconditions: None.
//Postconditions: Prompts the user to repeat or end the program.

void input(vector<int> &);
//Preconditions: None.
//Postconditions: Integer values typed in at the keyboard are read
//into the vector argument. Uses a sentinel value of -1 to end
//reading into the vector.

void sort(vector<int> &);
//Preconditions: None.
//Postconditions: The grades have been sorted in ascending order.

int getMaxScore(vector<int> &);
//Preconditions: The grades have been entered into a vector with a
//call to input.
//Postconditions: Returns the highest grade in the vector.

void buildHistogram(int*, vector<int> &, int);
//Preconditions: The grades have been entered into a vector with a
//call to input.
//Postconditions: Returns a pointer to the histogram.

void output(int*, int);
//Preconditions: The grades have been entered into a vector with a
//call to input and sorted into ascending order. Also, the
//function buildHistogram has been called.
//Postconditions: Displays the histogram to the screen.
//================================================================

int main()
{
	int max, *histogram;
	vector<int> grades;

	cout << "This is a program that constructs a histogram of student grades\n"
		 << "for an assignment.\n\n";

	do
	{
		input(grades);
		sort(grades);
		max = getMaxScore(grades);
		histogram = new int[max + 1];
		buildHistogram(histogram, grades, max);
		output(histogram, max);
		delete [] histogram;

	}while(!finished());

	_CrtDumpMemoryLeaks();

	return 0;
}

//Function Definitions
//================================================================
bool finished()
{
	string ans;

	do
	{
		cout << "Would you like to repeat the program? (Y/N): ";
		getline(cin, ans);
		cout << endl;

		if( (ans.find_first_not_of("YyNn") != string::npos) || (ans.length() > 1) )
			cout << "The response entered is not valid!\n";

	}while( (ans.find_first_not_of("YyNn") != string::npos) || (ans.length() > 1) );

	if(ans.find_first_of("Yy") != string::npos)
		return false;

	return true;
}
void input(vector<int> &vec)
{
	string grade;

	cout << "Enter the student grades for the assignment. Enter -1 to end the input.\n\n";

	do
	{
		cout << "Grade: ";
		getline(cin, grade);
		cout << endl;

		if( ((atoi(grade.c_str()) < 0) || (atoi(grade.c_str()) > 100)) && (atoi(grade.c_str()) != -1) )
			cout << "The student grade entered is not valid!\n";
		else if(atoi(grade.c_str()) == -1)
			return;
		else
			vec.push_back(atoi(grade.c_str()));

	}while( (atoi(grade.c_str()) >= 0) && (atoi(grade.c_str()) <= 100) );
}
void sort(vector<int> &vec)
{
	for(int index = 0; index < vec.size(); index++)
	{
		for(int nextIndex = index + 1; nextIndex < vec.size(); nextIndex++)
		{
			if(vec[nextIndex] < vec[index])
			{
				int temp = vec[nextIndex];
				vec[nextIndex] = vec[index];
				vec[index] = temp;
			}
		}
	}
}
int getMaxScore(vector<int> &vec)
{
	return (vec[vec.size() - 1]);
}
void buildHistogram(int *histogram, vector<int> &vec, int max)
{
	int count;

	for(int index = 0; index < max + 1; index++)
		histogram[index] = 0;

	for(int index = 0; index < vec.size(); index++)
	{
		count = 1;
		while(vec[index] == vec[index + 1])
		{
			count++;
			index++;
			if(index + 1 == vec.size())
				break;
		}
		
		histogram[vec[index]] = count;
	}
}
void output(int *histogram, int max)
{
	for(int index = 0; index < (max + 1); index++)
	{
		if(histogram[index] > 0)
		{
			cout << "Number of ";
			if(index >= 0 && index < 10)
				cout << index << "'s" << left << setw(5) << ":" << histogram[index] << endl;
			else if(index >= 10 && index < 100)
				cout << index << "'s" << left << setw(4) << ":" << histogram[index] << endl;
			else
				cout << index << "'s" << left << setw(3) << ":" << histogram[index] << endl;
		}
	}

	cout << endl;
}
//================================================================ 
Your vector<int> grades grows larger with each iteration of the main loop.
Thank you for your quick response. I was not aware or did not realize that vectors can leak memory. It was never mentioned in any of my classes and/or textbook. The only change that I made to my code is:

1
2
3
4
5
6
7
8
9
10
11
12
13
do
{
    vector<int> grades;
    input(grades);
    sort(grades);
    max = getMaxScore(grades);
    histogram = new int[max + 1];
    buildHistogram(histogram, grades, max);
    output(histogram, max);
    delete [] histogram;
    grades.resize(0);

}while(!finished());


Then proceeded to run the program again through the debugger and no memory was leaked. Thank you again for your help.
Well, it wasn't just a memory leak. If you tested the program, the existence of the previous set of data is visible in the output. Thus it wasn't some esoteric issues, but one affecting the output of the correct results, which ordinary testing should reveal.

resize() is ok, but clear() will do the job and perhaps documents the intention better.
http://www.cplusplus.com/reference/vector/vector/clear/
Topic archived. No new replies allowed.