>_<

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

It outputs a list of all the blocks to the debug console, like
{42} block ....

You take the 42 and assign it to something like _dbgBreakAlloc (read the manual to find out what it is actually called), then the allocator will stop when that block is allocated.

You then look at the stack contexts to find out where in your code that block is being allocated, then figure out why it isn't being freed.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.