Access Violation Error Help
I keep getting this message that I cant figure out how to fix.
Here is the error:
First-chance exception at 0x6380f8bc (msvcr90d.dll) in Final.exe: 0xC0000005: Access violation reading location 0xcdcdcdcd.
Unhandled exception at 0x6380f8bc (msvcr90d.dll) in Final.exe: 0xC0000005: Access violation reading location 0xcdcdcdcd.
And the symbols are not loading for: kernel32.dll and ntdll.dll.
What did I do wrong? ( I know that it has something to do with strlen and the buffer in the GetPet function.)
(if my code looks funny it is bucause it is an assignment for college. SOme of the things I have done here are a requirment; sorry. And I know that it has some C in it. This is something that I have been informed by my instructor as part of the learning process; vectors, structs, blah, blah, will come later next term.)
Here is my code:
Code:
#define _CRTDBG_MAP_ALLOC
#include < iostream >
#include < iomanip >
#include < cctype >
#include < cstring >
using std::cout;
using std::cin;
using std::endl;
using std::setw;
using namespace std;
//Variables
const int MAX = 60;
const int CAT = 20;
const int DOG = 35;
int menu_choice;
char again = 'Y';
char ** petName = new char * [12];
char ** ownName = new char * [12];
char ** petType = new char * [12];
int animalcount = 0;
int catCount = 0;
int dogCount = 0;
int totalCount = 0;
int count[60] = {0};
int * arrayCount = &count[0];
int catCost = 0;
int dogCost = 0;
int overallCost = 0;
int input = 0;
//Functions
void MenuChoice( int &menu_choice );
void ProcessMenu( int &menu_choice );
void GetPet( char **& petName, char **& ownName, char **& petType );
void DisplayAll();
void RemovePet( char **& petName, char **& ownName, char **& petType );
void TotalCat( int &catCount, int &catCost );
void TotalDog( int &dogCount, int &dogCost );
void TotalDay( int &overallCost, int &catCost, int &dogCost, int &totalCount );
void AvgCap( int * &arrayCount );
char Exit( char again );
int main()
{
//Test for Leaks.
_CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
//Function Pointers
void (*fn_ptr_Menu)( int & );
fn_ptr_Menu = MenuChoice;
void (*fn_ptr_Process)( int & );
fn_ptr_Process = ProcessMenu;
while( again == 'Y' )
{
fn_ptr_Menu( menu_choice );
fn_ptr_Process( menu_choice );
}
//Delete Memory.
for( int i = 0; i < 12; i++)
{
delete[] petName[i];
delete[] ownName[i];
delete[] petType[i];
}
delete[] petName;
delete[] ownName;
delete[] petType;
system( "pause" );
return 0;
}
/***********************************************************************************************************************
*Name: MenuChoice
*Parameters: &menu_choice
*Return: none
*Purpose: This function is to display the menu to the user.
***********************************************************************************************************************/
void MenuChoice( int &menu_choice )
{
cout << "\t\t\t\n\nMenu\n\n" << endl;
cout << "1) Board a Critter " << endl;
cout << "2) Remove a Critter " << endl;
cout << "3) Display all Critters " << endl;
cout << "4) Count all Critters and Calculate Daily Proceeds " << endl;
cout << "5) Exit " << endl;
cout << "\n\nPlease enter a menu choice, 1 to 5: " ;
cin >> menu_choice;
}
/***********************************************************************************************************************
*Name: ProcessMenu
*Parameters: &menu_choice
*Return: none
*Purpose: This function is to process the menu choice.
***********************************************************************************************************************/
void ProcessMenu( int &menu_choice )
{
//Function Pointer
void (*fn_ptr_disAll)();
fn_ptr_disAll = DisplayAll;
if( menu_choice < 1 || menu_choice > 5 )
{
cout << "\n\nPlease enter a number between 1 and 5! " << endl;
}
else
{
switch ( menu_choice)
{
case 1 ://Get Pet.
{
fn_ptr_disAll();
GetPet( petName, ownName, petType );
break;
}
case 2://Remove Pet
{
fn_ptr_disAll();
RemovePet( petName, ownName, petType );
break;
}
case 3://Display all info
{
fn_ptr_disAll();
break;
}
case 4://Display totals and avg
{
fn_ptr_disAll();
TotalCat( catCount, catCost );
TotalDog( dogCount, dogCost );
TotalDay( overallCost, catCost, dogCost, totalCount) ;
AvgCap(arrayCount);
break;
}
case 5://Exit the program
{
again = Exit( again );
break;
}
}
}
}
/***********************************************************************************************************************
*Name: GetPet
*Parameters: petName, ownName, petType
*Return: none
*Purpose: This function gets the pet info from the user and gets the counts.
***********************************************************************************************************************/
void GetPet( char **& petName, char **& ownName, char **& petType )
{
char buffer[256] = {0};
if( animalcount == 12)
{
cout << "\n\nYou cannot board anymore animals! You are at maximum capacity! " << endl;
}
else
{
cout << "Which cage number do you want to add the critter to? ( 1 to 12) ";
cin >> input;
if( input < 1 || input > 12 )
{
cout << "Please input a number between 1 and 12! " << endl;
}
else
{
int k = input - 1;
char * str = 0;
//Get input for the Pet Name, Owner name, and Pet Type.
cout << "\n\nPlease input Pet Name: ";
cin.ignore( cin.rdbuf()->in_avail() );
cin.getline( buffer, MAX );
cin.clear();
cin.ignore( cin.rdbuf()->in_avail() );
str = new char[strlen( buffer ) + 1];
strcpy( str, buffer );
petName[k] = str;
cout << "\n\nPlease input Owner Name: ";
cin.ignore( cin.rdbuf()->in_avail() );
cin.getline( buffer , MAX );
cin.clear();
cin.ignore( cin.rdbuf()->in_avail() );
str = new char[strlen( buffer ) + 1];
strcpy( str, buffer );
ownName[k] = str;
cout << "\n\nPlease input critter type: ";
cin.ignore( cin.rdbuf()->in_avail() );
cin.getline( buffer, MAX );
cin.clear();
cin.ignore( cin.rdbuf()->in_avail() );
str = new char[strlen( buffer ) + 1];
strcpy( str, buffer );
petType[k] = str;
//Add to the counts.
animalcount++;
totalCount ++;
//Add count to the avg array function helper.
* arrayCount = totalCount;
arrayCount++;
//cat count.
int result;
_strlwr( *petType );
result = strcmp( *petType, "cat" );
if( result == 0 )
{
catCount++;
}
//dog count.
int result1;
_strlwr( *petType );
result1 = strcmp( *petType, "dog" );
if( result1 == 0 )
{
dogCount++;
}
cout << "\n\nCritter " << input << ", has been added! " << endl;
}
}
}
/***********************************************************************************************************************
*Name: DisplayAll
*Parameters: none
*Return: none
*Purpose: This function displays all pet infomation to the user.
***********************************************************************************************************************/
void DisplayAll()
{
cout.setf( ios::left );
cout << setw(10) << "Cage Num." << setw(20) << "Pet Name" << setw(20) << "Owner's Name" << setw(20) << "Pet Type" << endl;
for( int i = 0; i < 12; i++ )
{
cout << setw(10) << i+1 << setw(20) << petName[i] << setw(20) << ownName[i] << setw(20) << petType[i] << endl;
}
}
/***********************************************************************************************************************
*Name: RemovePet
*Parameters: petName, ownName, petType
*Return: none
*Purpose: This function displays all pet infomation to the user.
***********************************************************************************************************************/
void RemovePet( char **& petName, char **& ownName, char **& petType )
{
cout << "Which cage number do you want to remove the critter from? ( 1 to 12) ";
cin >> input;
int j = input - 1;
//Delete memory
delete [] petName[j];
delete [] ownName[j];
delete [] petType[j];
//Correct the count
animalcount--;
cout << "\n\nCritter " << input << ", has been removed. " << endl;
}
/***********************************************************************************************************************
*Name: Exit
*Parameters: again
*Return: none
*Purpose: This function exits the program.
***********************************************************************************************************************/
char Exit( char again )
{
again = 'n';
return again;
}
/***********************************************************************************************************************
*Name: TotalCat
*Parameters: int &catCount, int &catCost
*Return: none
*Purpose: This function finds the cat costs and displays.
***********************************************************************************************************************/
void TotalCat( int &catCount, int &catCost )
{
catCost = catCount * CAT;
cout << "\n\nThe Amount of Cats today is: " << catCount << ". " << endl;
cout << "The Sum of today's Cat earnings is: " << catCost << ". " << endl;
}
/***********************************************************************************************************************
*Name: TotalDog
*Parameters: petType
*Return: none
*Purpose: This function finds the dog costs and displays.
***********************************************************************************************************************/
void TotalDog( int &dogCount, int &dogCost )
{
dogCost = dogCount * DOG;
cout << "\n\nThe Amount of Dogs today is: " << dogCount << ". " << endl;
cout << "The Sum of today's Dog earnings is: " << dogCost << ". " << endl;
}
/***********************************************************************************************************************
*Name: TotalDay
*Parameters: int &overallCost, int &catCost, int &dogCost, int &animalcount
*Return: none
*Purpose: This function finds the total for the day.
***********************************************************************************************************************/
void TotalDay( int &overallCost, int &catCost, int &dogCost, int &totalCount )
{
overallCost = catCost + dogCost;
cout << "\n\nThe Total Amount of Critters today is: " << totalCount << ". " << endl;
cout << "Total amount of animals right now: " << animalcount << ". " << endl;
cout << "The Sum of today's earnings is: " << overallCost << ". " << endl;
}
/***********************************************************************************************************************
*Name: AvgCap
*Parameters: none
*Return: none
*Purpose: This function finds the total avg for the day of animals.
***********************************************************************************************************************/
void AvgCap( int * &arrayCount )
{
int avg = 0;
int sum = 0;
arrayCount = &count[0];
for( int i = 0; i < totalCount; i++, arrayCount++ )
{
sum += * arrayCount;
}
avg = sum / totalCount;
cout << "\n\nThe Average Amount of Critters today is: " << avg << ". " << endl;
}
Re: Access Violation Error Help
This might be of some help to understand those debug markers: http://www.nobugs.org/developer/win3..._crt_heap.html
Other then that, it also might be esier if you do use C++, things like std::string, std::vector, etc. This is a good site.
Re: Access Violation Error Help
Alright. been messing with it a little bit and got most of it to work. I am leaking memory somewhere; cant figure it out. Something about a normal block line 155? Whenever I try to exit the program I get a heap assertion error.
Here is my new code:
Code:
#define _CRTDBG_MAP_ALLOC
#include < iostream >
#include < iomanip >
#include < cctype >
#include < cstring >
using std::cout;
using std::cin;
using std::endl;
using std::setw;
using namespace std;
//Variables
const int MAX = 60;
const int CAT = 20;
const int DOG = 35;
int menu_choice;
char again = 'Y';
char ** petName = new char * [256];
char ** petTemp = 0;
char ** ownName = new char * [256];
char ** ownTemp = 0;
char ** petType = new char * [256];
char ** typeTemp = 0;
int animalcount = 0;
int catCount = 0;
int dogCount = 0;
int totalCount = 0;
int count[60] = {0};
int * arrayCount = &count[0];
int catCost = 0;
int dogCost = 0;
int overallCost = 0;
int input = 0;
//Functions
void MenuChoice( int &menu_choice );
void ProcessMenu( int &menu_choice );
void GetPet( char **& petName, char **& ownName, char **& petType );
void DisplayAll();
void RemovePet( char **& petName, char **& ownName, char **& petType );
void TotalCat( int &catCount, int &catCost );
void TotalDog( int &dogCount, int &dogCost );
void TotalDay( int &overallCost, int &catCost, int &dogCost, int &totalCount );
void AvgCap( int * &arrayCount );
char Exit( char again );
int main()
{
//Test for Leaks.
_CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
//Function Pointers
void (*fn_ptr_Menu)( int & );
fn_ptr_Menu = MenuChoice;
void (*fn_ptr_Process)( int & );
fn_ptr_Process = ProcessMenu;
while( again == 'Y' )
{
MenuChoice( menu_choice );
ProcessMenu( menu_choice );
}
//Delete Memory.
for( int i = 0; i < animalcount; i++)
{
delete[] petName[i];
delete[] ownName[i];
delete[] petType[i];
}
system( "pause" );
return 0;
}
/***********************************************************************************************************************
*Name: MenuChoice
*Parameters: &menu_choice
*Return: none
*Purpose: This function is to display the menu to the user.
***********************************************************************************************************************/
void MenuChoice( int &menu_choice )
{
cout << "\t\t\t\n\nMenu\n\n" << endl;
cout << "1) Board a Critter " << endl;
cout << "2) Remove a Critter " << endl;
cout << "3) Display all Critters " << endl;
cout << "4) Count all Critters and Calculate Daily Proceeds " << endl;
cout << "5) Exit " << endl;
cout << "\n\nPlease enter a menu choice, 1 to 5: " ;
cin >> menu_choice;
}
/***********************************************************************************************************************
*Name: ProcessMenu
*Parameters: &menu_choice
*Return: none
*Purpose: This function is to process the menu choice.
***********************************************************************************************************************/
void ProcessMenu( int &menu_choice )
{
//Function Pointer
void (*fn_ptr_disAll)();
fn_ptr_disAll = DisplayAll;
if( menu_choice < 1 || menu_choice > 5 )
{
cout << "\n\nPlease enter a number between 1 and 5! " << endl;
}
else
{
switch ( menu_choice)
{
case 1 ://Get Pet.
{
GetPet( petName, ownName, petType );
break;
}
case 2://Remove Pet
{
DisplayAll();
RemovePet( petName, ownName, petType );
break;
}
case 3://Display all info
{
DisplayAll();
break;
}
case 4://Display totals and avg
{
DisplayAll();
TotalCat( catCount, catCost );
TotalDog( dogCount, dogCost );
TotalDay( overallCost, catCost, dogCost, totalCount) ;
AvgCap(arrayCount);
break;
}
case 5://Exit the program
{
again = Exit( again );
break;
}
}
}
}
/***********************************************************************************************************************
*Name: GetPet
*Parameters: petName, ownName, petType
*Return: none
*Purpose: This function gets the pet info from the user and gets the counts.
***********************************************************************************************************************/
void GetPet( char **& petName, char **& ownName, char **& petType )
{
//buffer.
char buffer[256] = {0};
//temp arrays
petTemp = new char * [animalcount + 1];
ownTemp = new char * [animalcount + 1];
typeTemp = new char * [animalcount + 1];
//addresses for temp
for( int i = 0; i < animalcount; i++ )
{
petTemp[i] = petName[i];
ownTemp[i] = ownName[i];
typeTemp[i] = petType[i];
}
if( animalcount == 12)
{
cout << "\n\nYou cannot board anymore animals! You are at maximum capacity! " << endl;
}
else
{
cout << "Which cage number do you want to add the critter to? ( 1 to 12) ";
cin >> input;
if( input < 1 || input > 12 )
{
cout << "Please input a number between 1 and 12! " << endl;
}
else
{
int k = input - 1;
//delete old information
delete [] petName;
delete [] ownName;
delete [] petType;
//Get input for the Pet Name, Owner name, and Pet Type.
cout << "\n\nPlease input Pet Name: ";
cin.ignore( cin.rdbuf()->in_avail() );
cin.getline( buffer, MAX );
cin.clear();
cin.ignore( cin.rdbuf()->in_avail() );
petTemp[k] = new char[strlen( buffer ) + 1];
strcpy( petTemp[k], buffer );
cout << "\n\nPlease input Owner Name: ";
cin.ignore( cin.rdbuf()->in_avail() );
cin.getline( buffer , MAX );
cin.clear();
cin.ignore( cin.rdbuf()->in_avail() );
ownTemp[k] = new char[strlen( buffer ) + 1];
strcpy( ownTemp[k], buffer );
cout << "\n\nPlease input critter type: ";
cin.ignore( cin.rdbuf()->in_avail() );
cin.getline( buffer, MAX );
cin.clear();
cin.ignore( cin.rdbuf()->in_avail() );
typeTemp[k] = new char[strlen( buffer ) + 1];
strcpy( typeTemp[k], buffer );
//add the new info.
petName = petTemp;
ownName = ownTemp;
petType = typeTemp;
//Add to the counts.
animalcount++;
totalCount ++;
//Add count to the avg array function helper.
* arrayCount = totalCount;
arrayCount++;
//cat count.
_strlwr( *petType );
char * breaker[10]= {0};
* breaker = petType[k];
int result;
result = strcmp( * breaker, "cat" );
int result1;
result1 = strcmp( * breaker, "dog" );
if( result == 0 )
{
catCount++;
}
if( result1 == 0 )
{
//dog count.
dogCount++;
}
cout << "\n\nCritter " << input << ", has been added! " << endl;
}
}
}
/***********************************************************************************************************************
*Name: DisplayAll
*Parameters: none
*Return: none
*Purpose: This function displays all pet infomation to the user.
***********************************************************************************************************************/
void DisplayAll()
{
cout.setf( ios::left );
cout << setw(10) << "Cage Num." << setw(20) << "Pet Name" << setw(20) << "Owner's Name" << setw(20) << "Pet Type" << endl;
for( int i = 0; i < totalCount; i++ )
{
cout << setw(10) << i+1 << setw(20) << petName[i] << setw(20) << ownName[i] << setw(20) << petType[i] << endl;
}
}
/***********************************************************************************************************************
*Name: RemovePet
*Parameters: petName, ownName, petType
*Return: none
*Purpose: This function displays all pet infomation to the user.
***********************************************************************************************************************/
void RemovePet( char **& petName, char **& ownName, char **& petType )
{
cout << "Which cage number do you want to remove the critter from? ( 1 to 12) ";
cin >> input;
int j = input - 1;
//delete old information
delete [] petName[j];
delete [] ownName[j];
delete [] petType[j];
strcpy( petName[j], "Empty" );
strcpy( ownName[j], "Empty" );
strcpy( petType[j], "Empty" );
//Correct the count
animalcount--;
cout << "\n\nCritter " << input << ", has been removed. " << endl;
}
/***********************************************************************************************************************
*Name: Exit
*Parameters: again
*Return: none
*Purpose: This function exits the program.
***********************************************************************************************************************/
char Exit( char again )
{
again = 'n';
return again;
}
/***********************************************************************************************************************
*Name: TotalCat
*Parameters: int &catCount, int &catCost
*Return: none
*Purpose: This function finds the cat costs and displays.
***********************************************************************************************************************/
void TotalCat( int &catCount, int &catCost )
{
catCost = catCount * CAT;
cout << "\n\nThe Amount of Cats today is: " << catCount << ". " << endl;
cout << "The Sum of today's Cat earnings is: " << catCost << ". " << endl;
}
/***********************************************************************************************************************
*Name: TotalDog
*Parameters: petType
*Return: none
*Purpose: This function finds the dog costs and displays.
***********************************************************************************************************************/
void TotalDog( int &dogCount, int &dogCost )
{
dogCost = dogCount * DOG;
cout << "\n\nThe Amount of Dogs today is: " << dogCount << ". " << endl;
cout << "The Sum of today's Dog earnings is: " << dogCost << ". " << endl;
}
/***********************************************************************************************************************
*Name: TotalDay
*Parameters: int &overallCost, int &catCost, int &dogCost, int &animalcount
*Return: none
*Purpose: This function finds the total for the day.
***********************************************************************************************************************/
void TotalDay( int &overallCost, int &catCost, int &dogCost, int &totalCount )
{
overallCost = catCost + dogCost;
cout << "\n\nThe Total Amount of Critters today is: " << totalCount << ". " << endl;
cout << "Total amount of animals right now: " << animalcount << ". " << endl;
cout << "The Sum of today's earnings is: " << overallCost << ". " << endl;
}
/***********************************************************************************************************************
*Name: AvgCap
*Parameters: none
*Return: none
*Purpose: This function finds the total avg for the day of animals.
***********************************************************************************************************************/
void AvgCap( int * &arrayCount )
{
int avg = 0;
int sum = 0;
arrayCount = &count[0];
for( int i = 0; i < totalCount; i++, arrayCount++ )
{
sum += * arrayCount;
}
avg = sum / totalCount;
cout << "\n\nThe Average Amount of Critters today is: " << avg << ". " << endl;
}
Re: Access Violation Error Help
Quote:
Originally Posted by
Shadow_Govt
Alright. been messing with it a little bit and got most of it to work. I am leaking memory somewhere; cant figure it out.
1) Have you used a debugger?
2) Do you see something wrong here?
Code:
//delete old information
delete [] petName[j];
delete [] ownName[j];
delete [] petType[j];
strcpy( petName[j], "Empty" );
strcpy( ownName[j], "Empty" );
strcpy( petType[j], "Empty" );
You've deleted petName[j], petOwner[j], etc. but then you start to write characters to the deleted memory. Why are you deleting the information? Why not just overwrite the information with the string "Empty" instead of deleting it?
Quote:
This is something that I have been informed by my instructor as part of the learning process; vectors, structs, blah, blah, will come later next term.
Sigh. Another bunch of students being taught C++ improperly. Not only is there the lack of usage of things that have been in C++ for over a decade now such as std::string and std::vector, you have this:
Code:
//Function Pointers
void (*fn_ptr_Menu)( int & );
fn_ptr_Menu = MenuChoice;
void (*fn_ptr_Process)( int & );
fn_ptr_Process = ProcessMenu;
Function pointers? Nope, you're learning 'C', which really does very little in learning C++. I would be bold and say you've wasted your money/time in the first semester (unless you want to write 'C' code), as all of this type of coding is discouraged when writing C++ programs.
Regards,
Paul McKenzie
Re: Access Violation Error Help
I tried the strcpy for just the info, that still causes an error in the heap.
Re: Access Violation Error Help
Quote:
Originally Posted by
Shadow_Govt
I tried the strcpy for just the info, that still causes an error in the heap.
I pointed out a glaring error. In no way was it guranteed to fix your entire program, however, it still was incorrect.
So do you see the headaches this type of coding produces? This is exactly why C++ was invented, so as to avert this type of memory management and handling.
Regards,
Paul McKenzie
Re: Access Violation Error Help
as I am going through the debugging, I am noticing "<bad ptr>" on all my new chars. Why would it do this? Is that what is causing this heap assertion?
Re: Access Violation Error Help
Also, maybe you should just write your own string and vector class. At the very least, all of that memory management would be localized instead of strewn about all over your code now.
You are allocating one place, deleting far from where the original allocation was done, and attempting to keep track of all of this with global variables. That is almost a guarantee things will not work.
You also did not answer my question about using a debugger. No programmer can write such code as you have without using a debugger.
Regards,
Paul McKenzie
Re: Access Violation Error Help
Quote:
Originally Posted by
Shadow_Govt
as I am going through the debugging, I am noticing "<bad ptr>" on all my new chars. Why would it do this? Is that what is causing this heap assertion?
You have multiple places with "new char". Where exactly are you refering to?
Regards,
Paul McKenzie
Re: Access Violation Error Help
Also, what is your input that reproduces the error? You didn't mention what menu option(s) you selected to reproduce the error.
Another thing:
Code:
char ** petName = new char * [12];
char ** ownName = new char * [12];
char ** petType = new char * [12];
Why is this being dynamically allocated? You know you have a maximumof 12, so just declare a normal array.
Code:
char *petName[12];
char *ownName[12];
char *petType [12];
Regards,
Paul McKenzie
Re: Access Violation Error Help
One of my requirements; Dynamically Allocated ragged arrays. Same with the function pointers. I know now that it has something to do with the buffer. While I was going through the debugging process, I noticed that as I was steping over, at the end of the program the buffer was filled with a very strange symbol. Almost like a bass music symbol.
Re: Access Violation Error Help
Quote:
Originally Posted by
Shadow_Govt
One of my requirements; Dynamically Allocated ragged arrays.
You never delete those arrays at the end of the program. That loop at the end of main() only deletes the individual entries in the array. Also, I see nothing "ragged". A ragged array would be one where one row has 5 entries, another row in the same array has 10 entries, etc. I don't see that going on at all in your program with that array. It's always going to be 12 slots for all three entries.
Secondly, if they are really "ragged", then why are you starting out immediately dynamically allocating them? They should only be allocated when necessary.
Code:
char ** petName = 0;
char ** ownName = 0;
char ** petType = 0;
And then when you add an entry, then and only then do you resize them.
Regards,
Paul McKenzie
Re: Access Violation Error Help
Code:
void GetPet( char **& petName, char **& ownName, char **& petType )
{
//buffer.
char buffer[256] = {0};
//temp arrays
petTemp = new char * [animalcount + 1];
ownTemp = new char * [animalcount + 1];
typeTemp = new char * [animalcount + 1];
//addresses for temp
for( int i = 0; i < animalcount; i++ )
{
petTemp[i] = petName[i];
ownTemp[i] = ownName[i];
typeTemp[i] = petType[i];
}
if( animalcount == 12)
This code is backwards. You should be testing first for the animal count. If it's 12, then you return. Then you go about and do all of the allocations only if the animalcount is less than 12.
It would also help you if you wrote functions to do the string and array resizing, instead of what you have now. Here is an example (not tested).
Code:
char *AssignNewString(const char* oldString, const char *newString)
{
if ( !oldString || !newString )
return 0;
unsigned int newSize = strlen(newString);
char *pTemp = new char [newSize+1];
pTemp = strlen(oldString + 1);
unsigned int nLenStr = strlen(oldString);
unsigned int minStringSize = min(nLenStr, newSize);
strncpy(pTemp, oldString, minStringSize);
pTemp[minStringSize] = '\0';
delete [] oldString;
return pTemp;
}
Then you call this instead of doing the gymnastics you're going through now with those global temp pointers, etc.
So instead of this:
Code:
//delete old information
delete [] petName;
delete [] ownName;
delete [] petType;
//Get input for the Pet Name, Owner name, and Pet Type.
cout << "\n\nPlease input Pet Name: ";
cin.ignore( cin.rdbuf()->in_avail() );
cin.getline( buffer, MAX );
cin.clear();
cin.ignore( cin.rdbuf()->in_avail() );
petTemp[k] = new char[strlen( buffer ) + 1];
strcpy( petTemp[k], buffer );
delete [] oldString
It becomes this:
Code:
cout << "\n\nPlease input Pet Name: ";
cin.ignore( cin.rdbuf()->in_avail() );
cin.getline( buffer, MAX );
cin.clear();
cin.ignore( cin.rdbuf()->in_avail() );
petName[k] = AssignNewString( petName[k], buffer);
The function is responsible for resizing the entry. If there is a problem, the code for getting you new string data is localized to that function. You then do a similar function for the arrays themselves.
Regards,
Paul McKenzie
Re: Access Violation Error Help
here is what I got now:
Code:
#define _CRTDBG_MAP_ALLOC
#include < iostream >
#include < iomanip >
#include < cctype >
#include < cstring >
using std::cout;
using std::cin;
using std::endl;
using std::setw;
using namespace std;
//Variables
const int MAX = 60;
const int CAT = 20;
const int DOG = 35;
int menu_choice;
char again = 'Y';
char ** petName = 0;
char ** petTemp = 0;
char ** ownName = 0;
char ** ownTemp = 0;
char ** petType = 0;
char ** typeTemp = 0;
int animalcount = 0;
int catCount = 0;
int dogCount = 0;
int totalCount = 0;
int count[60] = {0};
int * arrayCount = &count[0];
int catCost = 0;
int dogCost = 0;
int overallCost = 0;
int input = 0;
//Functions
void MenuChoice( int &menu_choice );
void ProcessMenu( int &menu_choice );
void GetPet( char **& petName, char **& ownName, char **& petType );
void DisplayAll();
void RemovePet( char **& petName, char **& ownName, char **& petType );
void TotalCat( int &catCount, int &catCost );
void TotalDog( int &dogCount, int &dogCost );
void TotalDay( int &overallCost, int &catCost, int &dogCost, int &totalCount );
void AvgCap( int * &arrayCount );
char Exit( char again );
int main()
{
//Test for Leaks.
_CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
//Memory Allocation
petName = new char * [256];
ownName = new char * [256];
petType = new char * [256];
//Function Pointers
void (*fn_ptr_Menu)( int & );
fn_ptr_Menu = MenuChoice;
void (*fn_ptr_Process)( int & );
fn_ptr_Process = ProcessMenu;
while( again == 'Y' )
{
fn_ptr_Menu( menu_choice );
fn_ptr_Process( menu_choice );
}
//Delete Memory.
for( int i = 0; i < totalCount + 1; i++)
{
delete[] petName[i];
delete[] ownName[i];
delete[] petType[i];
delete[] petTemp[i];
delete[] ownTemp[i];
delete[] typeTemp[i];
}
delete[] petName;
delete[] ownName;
delete[] petType;
delete[] petTemp;
delete[] ownTemp;
delete[] typeTemp;
system( "pause" );
return 0;
}
/***********************************************************************************************************************
*Name: MenuChoice
*Parameters: &menu_choice
*Return: none
*Purpose: This function is to display the menu to the user.
***********************************************************************************************************************/
void MenuChoice( int &menu_choice )
{
cout << "\t\t\t\n\nMenu\n\n" << endl;
cout << "1) Board a Critter " << endl;
cout << "2) Remove a Critter " << endl;
cout << "3) Display all Critters " << endl;
cout << "4) Count all Critters and Calculate Daily Proceeds " << endl;
cout << "5) Exit " << endl;
cout << "\n\nPlease enter a menu choice, 1 to 5: " ;
cin >> menu_choice;
}
/***********************************************************************************************************************
*Name: ProcessMenu
*Parameters: &menu_choice
*Return: none
*Purpose: This function is to process the menu choice.
***********************************************************************************************************************/
void ProcessMenu( int &menu_choice )
{
//Function Pointer
void (*fn_ptr_disAll)();
fn_ptr_disAll = DisplayAll;
if( menu_choice < 1 || menu_choice > 5 )
{
cout << "\n\nPlease enter a number between 1 and 5! " << endl;
}
else
{
switch ( menu_choice)
{
case 1 ://Get Pet.
{
GetPet( petName, ownName, petType );
break;
}
case 2://Remove Pet
{
fn_ptr_disAll();
RemovePet( petName, ownName, petType );
break;
}
case 3://Display all info
{
fn_ptr_disAll();
break;
}
case 4://Display totals and avg
{
TotalCat( catCount, catCost );
TotalDog( dogCount, dogCost );
TotalDay( overallCost, catCost, dogCost, totalCount) ;
AvgCap(arrayCount);
break;
}
case 5://Exit the program
{
again = Exit( again );
break;
}
}
}
}
/***********************************************************************************************************************
*Name: GetPet
*Parameters: petName, ownName, petType
*Return: none
*Purpose: This function gets the pet info from the user and gets the counts.
***********************************************************************************************************************/
void GetPet( char **& petName, char **& ownName, char **& petType )
{
if( animalcount == 12)
{
cout << "\n\nYou cannot board anymore animals! You are at maximum capacity! " << endl;
}
else
{
//buffer.
char buffer[MAX] = {0};
//temp arrays
petTemp = new char * [animalcount + 1];
ownTemp = new char * [animalcount + 1];
typeTemp = new char * [animalcount + 1];
//addresses for temp
for( int i = 0; i < animalcount; i++ )
{
petTemp[i] = petName[i];
ownTemp[i] = ownName[i];
typeTemp[i] = petType[i];
}
cout << "Which cage number do you want to add the critter to? ( 1 to 12) ";
cin >> input;
if( input < 1 || input > 12 )
{
cout << "Please input a number between 1 and 12! " << endl;
}
else
{
int k = input - 1;
//delete old information
delete [] petName;
delete [] ownName;
delete [] petType;
//Get input for the Pet Name, Owner name, and Pet Type.
cout << "\n\nPlease input Pet Name: ";
cin.ignore( cin.rdbuf()->in_avail() );
cin.getline( buffer, 20 );
cin.clear();
cin.ignore( cin.rdbuf()->in_avail() );
petTemp[k] = new char[strlen( buffer ) + 1];
strcpy( petTemp[k], buffer );
strcpy( buffer, " " );
cout << "\n\nPlease input Owner Name: ";
cin.ignore( cin.rdbuf()->in_avail() );
cin.getline( buffer , 20 );
cin.clear();
cin.ignore( cin.rdbuf()->in_avail() );
ownTemp[k] = new char[strlen( buffer ) + 1];
strcpy( ownTemp[k], buffer );
strcpy( buffer, " " );
cout << "\n\nPlease input critter type: ";
cin.ignore( cin.rdbuf()->in_avail() );
cin.getline( buffer, 10 );
cin.clear();
cin.ignore( cin.rdbuf()->in_avail() );
typeTemp[k] = new char[strlen( buffer ) + 1];
strcpy( typeTemp[k], buffer );
strcpy( buffer, " " );
//add the new info.
petName = petTemp;
ownName = ownTemp;
petType = typeTemp;
//Add to the counts.
animalcount++;
totalCount ++;
//Add count to the avg array function helper.
* arrayCount = totalCount;
arrayCount++;
//cat count.
_strlwr( *petType );
char * breaker[10]= {0};
* breaker = petType[k];
int result;
result = strcmp( * breaker, "cat" );
int result1;
result1 = strcmp( * breaker, "dog" );
if( result == 0 )
{
catCount++;
}
if( result1 == 0 )
{
//dog count.
dogCount++;
}
cout << "\n\nCritter " << input << ", has been added! " << endl;
}
}
}
/***********************************************************************************************************************
*Name: DisplayAll
*Parameters: none
*Return: none
*Purpose: This function displays all pet infomation to the user.
***********************************************************************************************************************/
void DisplayAll()
{
cout.setf( ios::left );
cout << setw(10) << "Cage Num." << setw(20) << "Pet Name" << setw(20) << "Owner's Name" << setw(20) << "Pet Type" << endl;
for( int i = 0; i < totalCount; i++ )
{
cout << setw(10) << i+1 << setw(20) << petName[i] << setw(20) << ownName[i] << setw(20) << petType[i] << endl;
}
}
/***********************************************************************************************************************
*Name: RemovePet
*Parameters: petName, ownName, petType
*Return: none
*Purpose: This function displays all pet infomation to the user.
***********************************************************************************************************************/
void RemovePet( char **& petName, char **& ownName, char **& petType )
{
cout << "Which cage number do you want to remove the critter from? ( 1 to 12) ";
cin >> input;
int j = input - 1;
//delete old information
delete [] petName[j];
delete [] ownName[j];
delete [] petType[j];
strcpy( petName[j], "Empty" );
strcpy( ownName[j], "Empty" );
strcpy( petType[j], "Empty" );
//Correct the count
animalcount--;
cout << "\n\nCritter " << input << ", has been removed. " << endl;
}
/***********************************************************************************************************************
*Name: Exit
*Parameters: again
*Return: none
*Purpose: This function exits the program.
***********************************************************************************************************************/
char Exit( char again )
{
again = 'n';
return again;
}
/***********************************************************************************************************************
*Name: TotalCat
*Parameters: int &catCount, int &catCost
*Return: none
*Purpose: This function finds the cat costs and displays.
***********************************************************************************************************************/
void TotalCat( int &catCount, int &catCost )
{
catCost = catCount * CAT;
cout << "\n\nThe Amount of Cats today is: " << catCount << ". " << endl;
cout << "The Sum of today's Cat earnings is: " << catCost << ". " << endl;
}
/***********************************************************************************************************************
*Name: TotalDog
*Parameters: petType
*Return: none
*Purpose: This function finds the dog costs and displays.
***********************************************************************************************************************/
void TotalDog( int &dogCount, int &dogCost )
{
dogCost = dogCount * DOG;
cout << "\n\nThe Amount of Dogs today is: " << dogCount << ". " << endl;
cout << "The Sum of today's Dog earnings is: " << dogCost << ". " << endl;
}
/***********************************************************************************************************************
*Name: TotalDay
*Parameters: int &overallCost, int &catCost, int &dogCost, int &animalcount
*Return: none
*Purpose: This function finds the total for the day.
***********************************************************************************************************************/
void TotalDay( int &overallCost, int &catCost, int &dogCost, int &totalCount )
{
overallCost = catCost + dogCost;
cout << "\n\nThe Total Amount of Critters today is: " << totalCount << ". " << endl;
cout << "Total amount of animals right now: " << animalcount << ". " << endl;
cout << "The Sum of today's earnings is: " << overallCost << ". " << endl;
}
/***********************************************************************************************************************
*Name: AvgCap
*Parameters: none
*Return: none
*Purpose: This function finds the total avg for the day of animals.
***********************************************************************************************************************/
void AvgCap( int * &arrayCount )
{
int avg = 0;
int sum = 0;
arrayCount = &count[0];
for( int i = 0; i < totalCount; i++, arrayCount++ )
{
sum += * arrayCount;
}
avg = sum / totalCount;
cout << "\n\nThe Average Amount of Critters today is: " << avg << ". " << endl;
}
I am getting "debug assertion" and if I start the program and try to exit without doing anything I get:
Unhandled exception at 0x62f831ea (msvcr90d.dll) in Final.exe: 0xC0000005: Access violation reading location 0xcdcdcdc1.
Re: Access Violation Error Help
Your right! Thanks for pointing that out.
Re: Access Violation Error Help
Quote:
Originally Posted by
Shadow_Govt
Your right! Thanks for pointing that out.
I made edits to my last post. If you write a function for resizing the string, and use that to get you new strings, that would, at the very least, neaten the code up somewhat so that it becomes easier to spot problems (and harder to make mistakes).
Note that the function takes care of everything -- allocation and deallocation -- this removes a lot of the "naked" calls to "delete[]" and "new char[]" all over your code. Remember that I did not test that function. If there is a bug, you will have to focus on it. But at least it moves the focus to a central location, and not all over your code.
I would also suggest you write a similar function for resizing the arrays of pet info. Something like this:
Code:
char **ResizePetInfo(char**& petInfo, unsigned int newSize)
{ ///
function here to do all of the resizing of the petInfo array
}
//...
petName = ResizePetInfo(petName, animalcount);
//...
Then this eliminates the naked new/delete calls you're making to resize the pet information. I am not going to write it, as it's your assignment.
Regards,
Paul McKenzie
Re: Access Violation Error Help
I noticed that the program works if I dont delete each individual element in the memory, but this causes leaks, and I cant have that. Where am I going wrong?
Here is the code:
Code:
#define _CRTDBG_MAP_ALLOC
#include < iostream >
#include < iomanip >
#include < cctype >
#include < cstring >
using std::cout;
using std::cin;
using std::endl;
using std::setw;
using namespace std;
//Variables
const int MAX = 60;
const int CAT = 20;
const int DOG = 35;
int menu_choice;
char again = 'Y';
char ** petName = 0;
char ** petTemp = 0;
char ** ownName = 0;
char ** ownTemp = 0;
char ** petType = 0;
char ** typeTemp = 0;
int animalcount = 0;
int catCount = 0;
int dogCount = 0;
int totalCount = 0;
int count[60] = {0};
int * arrayCount = &count[0];
int catCost = 0;
int dogCost = 0;
int overallCost = 0;
int input = 0;
//Functions
void MenuChoice( int &menu_choice );
void ProcessMenu( int &menu_choice );
void GetPet( char **& petName, char **& ownName, char **& petType );
void DisplayAll();
void RemovePet( char **& petName, char **& ownName, char **& petType );
void TotalCat( int &catCount, int &catCost );
void TotalDog( int &dogCount, int &dogCost );
void TotalDay( int &overallCost, int &catCost, int &dogCost, int &totalCount );
void AvgCap( int * &arrayCount );
char Exit( char again );
int main()
{
//Test for Leaks.
_CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
//Memory Allocation
petName = new char * [256];
ownName = new char * [256];
petType = new char * [256];
//Function Pointers
void (*fn_ptr_Menu)( int & );
fn_ptr_Menu = MenuChoice;
void (*fn_ptr_Process)( int & );
fn_ptr_Process = ProcessMenu;
while( again == 'Y' )
{
fn_ptr_Menu( menu_choice );
fn_ptr_Process( menu_choice );
}
//Delete Memory.
for( int i = 0; i < totalCount; i++)
{
delete[] petName[i];
delete[] ownName[i];
delete[] petType[i];
}
delete[] petName;
delete[] ownName;
delete[] petType;
system( "pause" );
return 0;
}
/***********************************************************************************************************************
*Name: MenuChoice
*Parameters: &menu_choice
*Return: none
*Purpose: This function is to display the menu to the user.
***********************************************************************************************************************/
void MenuChoice( int &menu_choice )
{
cout << "\t\t\t\n\nMenu\n\n" << endl;
cout << "1) Board a Critter " << endl;
cout << "2) Remove a Critter " << endl;
cout << "3) Display all Critters " << endl;
cout << "4) Count all Critters and Calculate Daily Proceeds " << endl;
cout << "5) Exit " << endl;
cout << "\n\nPlease enter a menu choice, 1 to 5: " ;
cin >> menu_choice;
}
/***********************************************************************************************************************
*Name: ProcessMenu
*Parameters: &menu_choice
*Return: none
*Purpose: This function is to process the menu choice.
***********************************************************************************************************************/
void ProcessMenu( int &menu_choice )
{
//Function Pointer
void (*fn_ptr_disAll)();
fn_ptr_disAll = DisplayAll;
if( menu_choice < 1 || menu_choice > 5 )
{
cout << "\n\nPlease enter a number between 1 and 5! " << endl;
}
else
{
switch ( menu_choice)
{
case 1 ://Get Pet.
{
GetPet( petName, ownName, petType );
break;
}
case 2://Remove Pet
{
fn_ptr_disAll();
RemovePet( petName, ownName, petType );
break;
}
case 3://Display all info
{
fn_ptr_disAll();
break;
}
case 4://Display totals and avg
{
TotalCat( catCount, catCost );
TotalDog( dogCount, dogCost );
TotalDay( overallCost, catCost, dogCost, totalCount) ;
AvgCap(arrayCount);
break;
}
case 5://Exit the program
{
again = Exit( again );
break;
}
}
}
}
/***********************************************************************************************************************
*Name: GetPet
*Parameters: petName, ownName, petType
*Return: none
*Purpose: This function gets the pet info from the user and gets the counts.
***********************************************************************************************************************/
void GetPet( char **& petName, char **& ownName, char **& petType )
{
if( animalcount == 12)
{
cout << "\n\nYou cannot board anymore animals! You are at maximum capacity! " << endl;
}
else
{
cout << "Which cage number do you want to add the critter to? ( 1 to 12) ";
cin >> input;
if( input < 1 || input > 12 )
{
cout << "Please input a number between 1 and 12! " << endl;
}
else
{
//buffer.
char buffer[MAX] = {0};
//temp arrays
petTemp = new char * [animalcount + 1];
ownTemp = new char * [animalcount + 1];
typeTemp = new char * [animalcount + 1];
//addresses for temp
for( int i = 0; i < animalcount; i++ )
{
petTemp[i] = petName[i];
ownTemp[i] = ownName[i];
typeTemp[i] = petType[i];
}
int k = input - 1;
//Get input for the Pet Name, Owner name, and Pet Type.
cout << "\n\nPlease input Pet Name: ";
cin.ignore( cin.rdbuf()->in_avail() );
cin.getline( buffer, 20 );
cin.clear();
cin.ignore( cin.rdbuf()->in_avail() );
petTemp[k] = new char[strlen( buffer ) + 1];
strcpy( petTemp[k], buffer );
cout << "\n\nPlease input Owner Name: ";
cin.ignore( cin.rdbuf()->in_avail() );
cin.getline( buffer , 20 );
cin.clear();
cin.ignore( cin.rdbuf()->in_avail() );
ownTemp[k] = new char[strlen( buffer ) + 1];
strcpy( ownTemp[k], buffer );
cout << "\n\nPlease input critter type ( cat / dog ): ";
cin.ignore( cin.rdbuf()->in_avail() );
cin.getline( buffer, 8 );
cin.clear();
cin.ignore( cin.rdbuf()->in_avail() );
typeTemp[k] = new char[strlen( buffer ) + 1];
strcpy( typeTemp[k], buffer );
//delete old information
delete [] petName;
delete [] ownName;
delete [] petType;
//add the new info.
petName = petTemp;
ownName = ownTemp;
petType = typeTemp;
//Add to the counts.
animalcount++;
totalCount ++;
//Add count to the avg array function helper.
* arrayCount = totalCount;
arrayCount++;
//cat count.
_strlwr( *petType );
char * breaker[10]= {0};
* breaker = petType[k];
int result;
result = strcmp( * breaker, "cat" );
int result1;
result1 = strcmp( * breaker, "dog" );
if( result == 0 )
{
catCount++;
}
if( result1 == 0 )
{
//dog count.
dogCount++;
}
cout << "\n\nCritter " << input << ", has been added! " << endl;
}
}
}
/***********************************************************************************************************************
*Name: DisplayAll
*Parameters: none
*Return: none
*Purpose: This function displays all pet infomation to the user.
***********************************************************************************************************************/
void DisplayAll()
{
cout.setf( ios::left );
cout << setw(10) << "Cage Num." << setw(20) << "Pet Name" << setw(20) << "Owner's Name" << setw(20) << "Pet Type" << endl;
for( int i = 0; i < totalCount; i++ )
{
cout << setw(10) << i+1 << setw(20) << petName[i] << setw(20) << ownName[i] << setw(20) << petType[i] << endl;
}
}
/***********************************************************************************************************************
*Name: RemovePet
*Parameters: petName, ownName, petType
*Return: none
*Purpose: This function displays all pet infomation to the user.
***********************************************************************************************************************/
void RemovePet( char **& petName, char **& ownName, char **& petType )
{
cout << "Which cage number do you want to remove the critter from? ( 1 to 12) ";
cin >> input;
if( input < 1 || input > 12 )
{
cout << "Please input a number between 1 and 12! " << endl;
}
else
{
int j = input - 1;
strcpy( petName[j], "Empty" );
strcpy( ownName[j], "Empty" );
strcpy( petType[j], "Empty" );
//Correct the count
animalcount--;
cout << "\n\nCritter " << input << ", has been removed. " << endl;
}
}
/***********************************************************************************************************************
*Name: Exit
*Parameters: again
*Return: none
*Purpose: This function exits the program.
***********************************************************************************************************************/
char Exit( char again )
{
again = 'n';
return again;
}
/***********************************************************************************************************************
*Name: TotalCat
*Parameters: int &catCount, int &catCost
*Return: none
*Purpose: This function finds the cat costs and displays.
***********************************************************************************************************************/
void TotalCat( int &catCount, int &catCost )
{
catCost = catCount * CAT;
cout << "\n\nThe Amount of Cats today is: " << catCount << ". " << endl;
cout << "The Sum of today's Cat earnings is: " << catCost << ". " << endl;
}
/***********************************************************************************************************************
*Name: TotalDog
*Parameters: petType
*Return: none
*Purpose: This function finds the dog costs and displays.
***********************************************************************************************************************/
void TotalDog( int &dogCount, int &dogCost )
{
dogCost = dogCount * DOG;
cout << "\n\nThe Amount of Dogs today is: " << dogCount << ". " << endl;
cout << "The Sum of today's Dog earnings is: " << dogCost << ". " << endl;
}
/***********************************************************************************************************************
*Name: TotalDay
*Parameters: int &overallCost, int &catCost, int &dogCost, int &animalcount
*Return: none
*Purpose: This function finds the total for the day.
***********************************************************************************************************************/
void TotalDay( int &overallCost, int &catCost, int &dogCost, int &totalCount )
{
overallCost = catCost + dogCost;
cout << "\n\nThe Total Amount of Critters today is: " << totalCount << ". " << endl;
cout << "Total amount of animals right now: " << animalcount << ". " << endl;
cout << "The Sum of today's earnings is: " << overallCost << ". " << endl;
}
/***********************************************************************************************************************
*Name: AvgCap
*Parameters: none
*Return: none
*Purpose: This function finds the total avg for the day of animals.
***********************************************************************************************************************/
void AvgCap( int * &arrayCount )
{
int avg = 0;
int sum = 0;
arrayCount = &count[0];
for( int i = 0; i < totalCount; i++, arrayCount++ )
{
sum += * arrayCount;
}
avg = sum / totalCount;
cout << "\n\nThe Average Amount of Critters today is: " << avg << ". " << endl;
}
Re: Access Violation Error Help
Quote:
Originally Posted by
Shadow_Govt
I noticed that the program works if I dont delete each individual element in the memory, but this causes leaks, and I cant have that. Where am I going wrong?
Remember that you have to do the debugging, as it's your assignment. Since your code is very hard to follow, here is some advice:
First, your dynamically allocated slots should have been initialized to 0. You didn't do that in the beginning of your program.
Second, notice that your input routines are practically identical. The only difference is the prompt and the array you're saving the information in. This is where you could have written a function, thus making the code much shorter and easier to follow and maintain.
Code:
void GetPet( char **& petName, char **& ownName, char **& petType )
{
if( animalcount == 12)
{
cout << "\n\nYou cannot board anymore animals! You are at maximum capacity! " << endl;
}
else
{
cout << "Which cage number do you want to add the critter to? ( 1 to 12) ";
cin >> input;
if( input < 1 || input > 12 )
{
cout << "Please input a number between 1 and 12! " << endl;
}
else
{
GetInput(&petName[input-1], "\n\nPlease input Pet Name: ");
GetInput(&ownName[input-1], "\n\nPlease input Owner Name: ");
GetInput(&petType[input-1], "\n\nPlease input critter type ( cat / dog ): ");
++animalcount;
}
}
}
That's practically the entire function.
GetInput() would look like this (lines missing):
Code:
void GetInput(char** pBuffer, const char* prompt)
{
char buffer[MAX];
// Write the input routine, but use the passed in prompt as the prompt
//.. For you to do
// Assign the new string
*pBuffer = AssignNewString( // parameters missing, you fill them in)
}
But I need to go back a few posts -- how do you really justify what I mentioned a few posts ago, and that is you do not have ragged arrays. Here is your exact input statement:
Code:
cout << "Which cage number do you want to add the critter to? ( 1 to 12) ";
cin >> input;
if( input < 1 || input > 12 )
{
cout << "Please input a number between 1 and 12! " << endl;
}
So you *do* have 12 slots, and only 12 slots. That is exactly why I don't understand the dynamic allocation of the "slots" array. There is no change in the number -- it's not as if you "grow" the number of slots on the fly -- it's always 12. Otherwise, that input above doesn't make logical sense.
The only thing dynamic in this assignment that I see is the string generation. Then yes, you don't know how long the input strings will be, so you dynamically allocate. That is a different story than the slots you are placing the strings in.
I'm saying all of this because hardly anyone here will want to work with the code you posted as it stands, so the best thing you could do is organize it in a way that is "user friendly" or more plainly, "helper friendly". I mentioned already to write a function, but you didn't do that.
Speaking of which, here is a better version of AssignNewString. Note that in the code above in GetInput, all you have to do is call it with the appropriate parameters.
Code:
char *AssignNewString(const char* oldString, const char *newString)
{
if ( !newString )
return 0;
unsigned int newSize = strlen(newString);
char *pTemp = new char [newSize+1];
strcpy(pTemp, newString);
delete [] oldString;
return pTemp;
}
I made amendments to the function, but you should have at least attempted to write this function to remove and "resize" a string with new data.
So, just this alone shows that the code need not be messy. Anytime you are asked to do an assignment like this, the best you can do is not to compound the problem by being as messy as the assignment given. You try and compartmentalize the code into blocks (i.e. functions) that handle the details. Now, if there is a problem in allocating the strings, I know exactly where to go, and that is AssignNewString. If there is something wrong with the input, again, it is in GetInput().
Regards,
Paul McKenzie