-
pointer always NULL?
I am trying to create a Competitor-derived object from user input. The code below is where this should happen, the getCompetitorData(...) function creates the object but when control is returned to the calling block of code the pointer is equal to NULL again. Why is this? I cant see any problems in the code so this is my last resort before redoing the whole program :(
Code:
Competitor* newCompetitor = NULL;
switch( option )
{
case 1:
if( ! getCompetitorData( comp, newCompetitor ) )
{
cerr << "competitor not created";
exit( 0 );
}
if( newCompetitor == NULL )
{
cerr << "newCompetitor==NULL, editMenu()"; //why should it be NULL??
Sleep( 5000 );
exit( 0 );
}
comp.addCompetitor( newCompetitor );
if( newCompetitor != NULL )
delete newCompetitor;
newCompetitor = NULL;
system( "cls" );
cout << "\nThis competition has " << comp.countRecords( ) << " entries so far" << endl;
break;
default:
break;
}
//getCmpetitorData(...)
Code:
bool getCompetitorData( Competition& comp, Competitor* empty)
{
system( "cls" );
char first[ MAX ];
cout << "\nEnter first name : ";
cin.getline( first, MAX, '\n' );
char last[ MAX ];
cout << "\nEnter last name : ";
cin.getline( last, MAX, '\n' );
int age;
cout << "\nEnter age : ";
cin >> age;
cin.ignore( 80, '\n' );
if( !cin.good( ) )
{
cerr << "Bad input fool!" << endl;
return false;
}
char sex;
cout << "\nSex ( M or F ): ";
cin >> sex;
cin.ignore( 80, '\n' );
SEX enumSex;
if( sex != 'm' && sex != 'M' && sex != 'f' && sex != 'F' )
{
cerr << "Bad input fool!" << endl;
return false;
}
else
{
(sex == 'm' || sex == 'M' ) ? enumSex = MALE : enumSex = FEMALE;
}
char school[ MAX ];
cout << "\nEnter name of Taekwon-do school : ";
cin.getline( school, MAX, '\n' );
char grade;
cout << "\nEnter competitors grade ( Y, G, B, R, 1, 2, 3 or 4 ) : ";
cin >> grade;
GRADE enumGrade;
switch( grade )
{
case 'y':
case 'Y':
enumGrade = YELLOW;
break;
case 'g':
case 'G':
enumGrade = GREEN;
break;
case 'b':
case 'B':
enumGrade = BLUE;
break;
case 'r':
case 'R':
enumGrade = RED;
case '1':
enumGrade = FIRST;
break;
case '2':
enumGrade = SECOND;
case '3':
enumGrade = THIRD;
case '4':
enumGrade = FOURTH;
break;
default:
cerr << "Bad input fool!!" << endl;
return false;
}
int heightOrWeight;
cout << ( age < 18 ? "\nEnter height ( cm ): " : "\nEnter weight ( kg ) : " );
cin >> heightOrWeight;
cin.ignore( 80, '\n' );
if( !cin.good( ) )
{
cerr << "Bad input fool!" << endl;
return false;
}
char spar, patterns, power, special;
cout << "\nEvents entered - y or n: " << endl;
cout << "Sparring : ";
cin.get( spar );
cin.ignore( 80, '\n' );
if( checkYesNoInput( spar ) )
return false;
cout << "\nPatterns : ";
cin.get( patterns );
cin.ignore( 80, '\n' );
if( checkYesNoInput( patterns ) )
return false;
cout << "\nPower : ";
cin.get( power );
cin.ignore( 80, '\n' );
if( checkYesNoInput( power ) )
return false;
cout << "\nSpecial technique : ";
cin.get( special );
cin.ignore( 80, '\n' );
if( checkYesNoInput( special ) )
return false;
if( age >= 18 )
{
try
{
empty = new Adult( first, last, age, enumGrade, enumSex, school,
checkYesOrNo( spar ), checkYesOrNo( patterns ), checkYesOrNo( power ), checkYesOrNo( special ), heightOrWeight );
}catch( bad_alloc ex )
{
cerr << "bad_alloc caught, Adult not created" << endl;
}
}
else
{
try
{
empty = new Child( first, last, age, enumGrade, enumSex, school,
checkYesOrNo( spar ), checkYesOrNo( patterns ), checkYesOrNo( power ), checkYesOrNo( special ), heightOrWeight );
}catch( bad_alloc ex )
{
cerr << "bad_alloc caught, Child not created" << endl;
}
}
return true;
}
When is gets to the addCompetitor(...) the pointer is NULL again.
tia
-
The reason why it's not working is that you pass a pointer to NULL. You need to pass the address of that pointer so the new pointer (allocated with new) can be stored in that address. Try something like this:
Code:
getCompetitorData( comp, &newCompetitor )
...
...
bool getCompetitorData( Competition& comp, Competitor **empty)
...
*empty = new Adult( first, last, age, enumGrade, ...
-
>Why is this?
Pointers are just like any other variable, if you want to change what the pointer points to in another function then you must pass it by its address:
Code:
#include <iostream>
// When defined, the allocation will not work in main.
#define FAIL_CHECK
int allocMem1 ( int *empty )
{
empty = new int;
if ( empty == NULL )
return 2;
return 1;
}
int allocMem2 ( int **empty )
{
*empty = new int;
if ( *empty == NULL )
return 2;
return 1;
}
int main()
{
int *var = NULL;
#ifdef FAIL_CHECK
if ( allocMem1 ( var ) == 1 ) {
#else
if ( allocMem2 ( &var ) == 1 ) {
#endif
if ( var == NULL )
std::cout<<"It didn't work\n";
else
std::cout<<"It did work!\n";
}
return 0;
}
Try running the program with FAIL_CHECK defined and then run it with FAIL_CHECK commented out to see the difference between allocMem1 and allocMem2.
-Prelude
-
Or:
bool getCompetitorData( Competition& comp, Competitor* &empty)
-
What you could also do is to return the pointer and then assign it.
You would then also do some tests to check if the function worked properly so to speak.
Code:
Competitor* getCompetitorData( Competition& comp, Competitor* empty)
-
Thanks all, that should keep me going for a while....