Problem with linked list

Started by
33 comments, last by SiCrane 14 years, 10 months ago
I am trying to program a Workout log, compiling it step by stet to see if there is any problem. As always, there is one. When I build it, it gives me no errors, and I am able to compile it. But during runtime it stops executing and the system crashes I am not sure why. However I did debug it found the problem lies with the vector string I created. The program crashes when it reaches the for loop, more specifically when I call for the vector.size(); here is the relavent code,although ask if you need to see more :


void workOutRoutine::AddNode()
{
	system("cls"); //Could not resist

	unsigned int i(0),j(0);

	//Used to add new node
	workOutRoutine *Temp = new workOutRoutine;
	//Used to determine the end of the list to add new node
	workOutRoutine *EndList; 

	//Dummy variable 
	//getline reads \n
	string dummy;
	getline(cin,dummy);

	//Get Day Of workout;
	cout<<"Enter the Day : ";
	getline(cin,Temp->Day);
	cout<<endl;
	//Get body thats being worked out
	cout<<"Which Body Part is Worked out on "<<Temp->Day<<"\t";
	getline(cin,Temp->bodyPart);
	cout<<endl;

	//Add the type of workout
	//on the unique body part
	//and the number of sets
	//each with certain weight
	for(i =0; i <= Exercise.size(); i++) //<--- PROBLEM LIES WITHIN "Exercise.size(). While degugging it crashes my program.
	{
		if(i == Exercise.size()-1)
		{
			cout<<"\nWould You like to add more sets to your "<<Temp->bodyPart<<" workout (y/n) ";
			char opt;
			cin >> opt;

			//NOT SURE IF THIS PART WORKS THE WAY I WANT IT TO,
			//BUT I'LL DEAL WITH THAT AFTER THIS BUG IS FIXED
			if(opt == 'y' || opt == 'Y') 
			{
				cout<<"\nAdding another Workout Element...";
				Exercise.resize(Exercise.size()+1,vector<string>(Exercise.size()+1));
				cout<<"\nDone adding another Element"<<endl;
			}
			
			else break;

		}

		cout<<"What type of "<<Temp->bodyPart<<" workout did you do : ";
		getline(cin,Exercise[0]); // [0] is the Identifier or type of workout
		cout<<"\n"<<endl;

			for(j = 1; i< Exercise.size(); j++)
			{
				cout<<"Enter the weight lifted for set # "<<++j<<"  :  ";
				getline(cin,Exercise[j]);
			}

	}

	//Get Additional Info
	cout<<"If you did any extra 'workout' the enter keywords with time like basketball(30.00 minutes),running(10.00 minutes)\n";
	cout<<"else enter NONE :  ";
	getline(cin,Extra);

	cout<<"\nWhat do you estimate the total time you took to workout :  ";
	getline(cin,TotalTime);
	
	

	//Check to see if any node has been alocated
	if(strt == NULL)
	{
		strt = Temp;
		strt->NextNode = NULL;
		return;

	}
	else
	{	//set endlist pointer to start of the list
		EndList = strt;

		//Move to the end of the list
		while(EndList->NextNode != NULL)
			EndList = EndList->NextNode;

		EndList = Temp; //Add new node
		EndList->NextNode = NULL;

	}
}

Regards, Tnutty
Our whole life is a opengl application.
Advertisement
Are you sure that the pointer you're calling AddNode() on is valid?
Yes, I think so, here is the full code

#include<iostream>#include<string>#include<vector>#include<windows.h>using namespace std;//Min number of Exercie that I will do per Workoutconst unsigned int MIN_EXERCISE = 3;//The number of sets/exercise done //for a particular workoutconst unsigned int MIN_SETS = 4;//Class hold every info about the type of workout, which days it on// which body part, how many sets, how much weight lifted per set, and //the time it toolclass workOutRoutine{public: 	//The day of workout	string Day;	//The body part thats being worked out	string bodyPart;	//The type of exercise begin used	//And how many times being done	//Exercise[x][0] is Exercise identifier	//Exercise[x][y] is the weight lifted	vector<vector<string> > Exercise;	//Any extra exercise done	string Extra;	//The time spent during a particular day of working out	string TotalTime;	workOutRoutine *NextNode;public:	workOutRoutine();	void AddNode();	void PrintInfo();	bool DeleteFirstNode();	bool DeleteLastNode();	bool DeleteCurrentNode();	void MoveRight();	void ModeLeft();	bool SaveToFile();} *strt,*curr;//The constructorworkOutRoutine::workOutRoutine(){	//set strt so that its empty	strt = NULL;	curr = strt;	//Resize vector to the minimun number of exercise that 	//I will do and to the minimum number of sets	Exercise.resize(MIN_EXERCISE,vector<string>(MIN_SETS,"NONE"));	}void workOutRoutine::AddNode(){	system("cls");	unsigned int i(0),j(0);	//Used to add new node	workOutRoutine *Temp = new workOutRoutine;	//Used to determine the end of the list to add new node	workOutRoutine *EndList; 	//Dummy variable 	//getline reads \n	string dummy;	getline(cin,dummy);	//Get Day Of workout;	cout<<"Enter the Day : ";	getline(cin,Temp->Day);	cout<<endl;	//Get body thats being worked out	cout<<"Which Body Part is Worked out on "<<Temp->Day<<"\t";	getline(cin,Temp->bodyPart);	cout<<endl;	//Add the type of workout	//on the unique body part	//and the number of sets	//each with certain weight	for(i =0; i <=Exercise.size(); i++)	{		if(i == Exercise.size()-1)		{			cout<<"\nWould You like to add more sets to your "<<Temp->bodyPart<<" workout (y/n) ";			char opt;			cin >> opt;						if(opt == 'y' || opt == 'Y')			{				cout<<"\nAdding another Workout Element...";				Exercise.resize(Exercise.size()+1,vector<string>(Exercise.size()+1));				cout<<"\nDone adding another Element"<<endl;			}						else break;		}		cout<<"What type of "<<Temp->bodyPart<<" workout did you do : ";		getline(cin,Exercise[0]); // [0] is the Identifier or type of workout		cout<<"\n"<<endl;			for(j = 1; i< Exercise.size(); j++)			{				cout<<"Enter the weight lifted for set # "<<++j<<"  :  ";				getline(cin,Exercise[j]);			}	}	//Get Additional Info	cout<<"If you did any extra 'workout' the enter keywords with time like basketball(30.00 minutes),running(10.00 minutes)\n";	cout<<"else enter NONE :  ";	getline(cin,Extra);	cout<<"\nWhat do you estimate the total time you took to workout :  ";	getline(cin,TotalTime);			//Check to see if any node has been alocated	if(strt == NULL)	{		strt = Temp;		strt->NextNode = NULL;		return;	}	else	{	//set endlist pointer to start of the list		EndList = strt;		//Move to the end of the list		while(EndList->NextNode != NULL)			EndList = EndList->NextNode;		EndList = Temp; //Add new node		EndList->NextNode = NULL;	}}void workOutRoutine::PrintInfo(){	workOutRoutine *Temp = strt;	//Check if any node exist	if(Temp == NULL)	{		cout<<"No routine at this point\n\n";		return;	}	//Print all Info	while(Temp != NULL)	{		cout<<"Day of Week "<<Temp->Day<<endl;		cout<<"Body Part worked out : "<<Temp->bodyPart<<endl;		for(unsigned int i = 0; i<Exercise.size(); i++)		{			//Exercise[0] represents Workout Type/ID			cout<<"Type of Workout #"<<i<<"\t\t"<<Temp->Exercise[0]<<endl;			for(unsigned int j = 1; j< Exercise.size(); j++)			{				//Exercise weight lifted				cout<<"\t  Set #"<<i<<" : "<<Exercise[j]<<endl;			}		}				cout<<endl<<endl;			}}int Options(int opt){	cout<<"1 -- Add Day to workout"<<endl;	cout<<"2 -- Move Node forward"<<endl;	cout<<"3 -- Move Node Backward"<<endl;	cout<<"4 -- Delete current Node"<<endl;	cout<<"5 -- Delete First Node"<<endl;	cout<<"6 -- Delete Last Node"<<endl;	cout<<"7 -- Save Info to File"<<endl;	cout<<"8 -- Load Info to File"<<endl<<endl;	cin >> opt;	return opt;}int main(){	int opt = -1;	//Call the constructor 	workOutRoutine();	do	{		system("cls");		strt->PrintInfo();		cout<<"\n\n"<<endl;				//Get uses input		opt = Options(opt);		switch(opt)		{			case 1:	strt->AddNode();		break;			case 2:			break;			case 3:			break;			case 4:			break;			case 5:			break;			case 6:			break;			case 7:			break;			case 8:			break;		}	}while(opt != 0);}		
Our whole life is a opengl application.
Where do you initialize strt?
the Ctor
workOutRoutine::workOutRoutine(){	//set strt so that its empty	strt = NULL;	curr = strt;	//Resize vector to the minimun number of exercise that 	//I will do and to the minimum number of sets	Exercise.resize(MIN_EXERCISE,vector<string>(MIN_SETS,"NONE"));	}
Our whole life is a opengl application.
You may not realize this, but NULL is not a valid pointer value to call a member function on.
I tried this before with another linked list program and it gave no problem.

If set it to null in main, it gives the same problem.

Here is the error:
Unhandled exception at 0x008132e9 in ExerciseRoutine.exe: 0xC0000005: Access violation reading location 0x0000004c.


Our whole life is a opengl application.
The size function is 1..n not 0..n ( use less-than not less-than-equal)

for(i =0; i <= Exercise.size(); i++)


it tries to iterate one step further than the actual size

... that at least for a start.


Its one of the most common errors -- an 'off by one' error
--------------------------------------------[size="1"]Ratings are Opinion, not Fact
Quote:Original post by wodinoneeye
The size function is 1..n not 0..n ( use less-than not less-than-equal)

for(i =0; i <= Exercise.size(); i++)


it tries to iterate one step further than the actual size

... that at least for a start.


Its one of the most common errors -- an 'off by one' error




I do this to make push_back func work
when (i) reaches vec.Size(), since it starts from 0, its 1 size passed it, so I
call push_back method if I want to add more sets.

if(i == Exercise.size())		{			cout<<"\nWould You like to add more sets to your "<<Temp->bodyPart<<" workout (y/n) ";			char opt;			cin >> opt;						if(opt == 'y' || opt == 'Y')			{				cout<<"\nAdding another Workout Element...";				Exercise.resize(Exercise.size()+1,vector<string>(Exercise.size()+1));				cout<<"\nDone adding another Element"<<endl;			}


Our whole life is a opengl application.
Quote:Original post by tnutty
If set it to null in main, it gives the same problem.


Quote:Original post by SiCrane
You may not realize this, but NULL is not a valid pointer value to call a member function on.


This topic is closed to new replies.

Advertisement