>_<
I've been searching for nearly an hour and trying to find this memory leak. If you guys could help me find it it would be great. Thx.
#include <iostream>
#include <cstring>
#include <crtdbg.h>
using std::cout;
using std::cin;
using std::ios_base;
/////////////// user defined data /////////////////////
/////////////// function prototypes ////////////////////
class State
{
public:
int initState (char * name, int year, char * cap, int popRank);
void deleteState ();
void copyState (State & tempState);
void printState ();
private:
char * name; // state name
int year; // year of entry into the union
char * cap; // state capital
int popRank; // population ranking
};
class Database
{
public:
int initDatabase (char * file = "states.txt");
void deleteDatabase ();
void fillDatabase ();
void insertDatabase (int index, State & tempState);
void printDatabase ();
private:
State * list; // array of states
int count; // total count of states
char * filename; // input filename
};
////////////////////////// program start ///////////////////////////////////////
int main(void)
{
Database db;
if ( db.initDatabase() )
{
// then initialize fields of Database struct
db.fillDatabase(); // read from file
db.printDatabase(); // print data
db.deleteDatabase(); // free memory in Database struct
cout << '\n' << (_CrtDumpMemoryLeaks() ? "Memory Leak\n" : "No Leak");
return 0;
}
else // not successful
{
return 1;
}
}
////////////////////// Database functions ////////////////////////////////
//initDatabase - allocates memory for Database struct and initializes
// each field
//input: input filename
//return: pointer to Database struct if success
// NULL if fail
int Database::initDatabase (char * file)
{
FILE * fpIn;
char * string;
State * states;
// open input file and check for open success
if ( ( fpIn = fopen( file, "r" ) ) )
{
// allocate memory for Database struct and check for success
// allocate memory for filename field and initializes with filename
if ( string = new char[strlen( file ) + 1] )
{
strcpy( string, file );
filename = string;
}
else
{
cout << "Not enough memory!" << '\n';
delete [] string;
return 0;
}
// initialize count field to 50
count = 50;
// initialize list field by allocating memory for array of 50 states
// and check for success
if ( states = new State[50] )
{
list = states;
}
else
{
cout << "Not enough memory!" << '\n';
delete [] states;
return 0;
}
}
// close input file
fclose( fpIn );
return 1;
}
//deleteDatabase - frees allocated memory inside a Database struct
//input: pointer to Database struct
//return: nothing
void Database::deleteDatabase ()
{
for ( int cnt = 0; cnt < count; cnt++ )
list[cnt].deleteState();
delete [] filename;
delete [] list;
}
//fillDatabase - reads info from file and stores in array of State structs
//input: pointer to Database struct
//return: nothing
void Database::fillDatabase ()
{
State tempState; // temp State struct to store data from file
char name[80]; // temp variables
int year; // to store
char cap[80]; // input data
int popRank; // from file
int index = 0; // index into array of State structs
// open file from filename field of db
// don't need to check for file open success because initDatabase already checked
FILE *fpIn = fopen( filename, "r" );
// loop through all the states
for ( int cnt = 0; cnt < count; cnt++ )
{
// read and parse one line of file into 4 input data fields
if ( fscanf( fpIn, "%[^,], %d, %[^,], %d", name, &year, cap, &popRank ) == 4 )
{
// if tempState is created successfully from the 4 input data
if ( tempState.initState (name, year, cap, popRank) )
{ // then copy tempState data into array of states at the current index
insertDatabase (index, tempState);
}
index++;
}
else
{
cout << "Error reading file!" << '\n';
exit(0);
}
}
// close file
fclose( fpIn );
}
//insertDatabase - copy state data from tempState into appropriate place in array
//input: pointer to Database struct
// current index in array
// pointer to tempState containing state data
//return: nothing
void Database::insertDatabase (int index, State & tempState)
{
// set pCurrent to location to be inserted in array
State * pCurrent = list + index;
// copy from state to pCurrent
(*pCurrent).copyState( tempState );
return;
}
//printDatabase - print data of state array
//input: pointer to Database struct
//return: nothing
void Database::printDatabase ()
{
cout << " State name Year Capital Pop. rank" << '\n';
cout << "------------------------------------------------" << '\n';
for (int i = 0; i < count; i++)
list[i].printState();
return;
}
//////////////////////// State functions //////////////////////////////
//initState - initializes a State struct with input data
//input: pointer to State struct
// name, year, capital, and population rank of state
//return: true for success
// false for fail
int State::initState (char * tempName, int tempYear, char * tempCap, int tempPopRank)
{
char * stateName;
char * capital;
// if memory allocation is successful, store name
if ( stateName = new char[strlen( tempName ) + 1 ] )
{
strcpy( stateName, tempName );
name = stateName;
}
else
{
cout << "Not enough memory!" << '\n';
delete [] stateName;
return 0;
}
// store year
year = tempYear;
// if memory allocation is successful, store capital
if ( capital = new char[strlen( tempCap ) + 1 ] )
{
strcpy( capital, tempCap );
cap = capital;
}
else
{
cout << "Not enough memory!" << '\n';
delete [] capital;
return 0;
}
// store population ranking
popRank = tempPopRank;
return 1;
}
//deleteState - frees allocated memory inside a State struct
//input: pointer to State struct
//return: nothing
void State::deleteState ()
{
delete [] name;
delete [] cap;
}
//copyState - copies contents between two State structs
//input: pointer to source State struct
// pointer to destination State struct
//return: nothing
void State::copyState (State & tempState)
{
name = tempState.name;
year = tempState.year;
cap = tempState.cap;
popRank = tempState.popRank;
}
//printState - displays State data
//input: pointer to State struct
//return: nothing
void State::printState ()
{
cout.setf(ios_base::left);
cout.width(17);
cout << name;
cout.setf(ios_base::left);
cout.width(8);
cout << year;
cout.setf(ios_base::left);
cout.width(18);
cout << cap ;
cout.setf(ios_base::left);
cout.width(2);
cout << popRank << '\n';
return;
}
////////////////////////// program end ////////////////////////////////////
here is the states.txt file:
Connecticut,1788,Hartford,29
Maine,1820,Augusta,40
Massachusetts,1788,Boston,13
New Hampshire,1788,Concord,41
Rhode Island,1790,Providence,43
Vermont,1791,Montpelier,49
Delaware,1787,Dover,45
Maryland,1788,Annapolis,19
New Jersey,1787,Trenton,10
New York,1788,Albany,3
Pennsylvania,1787,Harrisburg,6
Alabama,1819,Montgomery,23
Arkansas,1836,Little Rock,32
Florida,1845,Tallahassee,4
Georgia,1788,Atlanta,9
Kentucky,1792,Frankfort,26
Louisiana,1812,Baton Rouge,24
Mississippi,1817,Jackson,31
Missouri,1821,Jefferson City,17
North Carolina,1789,Raleigh,11
South Carolina,1788,Columbia,25
Tennessee,1796,Nashville,16
Virginia,1788,Richmond,12
West Virginia,1863,Charleston,37
Illinois,1818,Springfield,5
Indiana,1816,Indianapolis,14
Iowa,1846,Des Moines,30
Kansas,1861,Topeka,33
Michigan,1837,Lansing,8
Minnesota,1858,St. Paul,21
Nebraska,1867,Lincoln,38
North Dakota,1889,Bismarck,11
Ohio,1803,Columbus,7
South Dakota,1889,Pierre,46
Wisconsin,1848,Madison,20
Arizona,1912,Phoenix,18
New Mexico,1912,Santa Fe,36
Oklahoma,1907,Oklahoma City,28
Texas,1845,Austin,2
Alaska,1959,Juneau,47
California,1850,Sacramento,1
Colorado,1867,Denver,22
Hawaii,1959,Honolulu,42
Idaho,1890,Boise,39
Montana,1889,Helena,44
Nevada,1864,Carson City,35
Oregon,1859,Salem,27
Utah,1896,Salt Lake City,34
Washington,1889,Olympia,15
Wyoming,1890,Cheyenne,50