antos
asked on
Passing an array to funciton, part of the array object is lost ?
I have a match struct as:
class Match{
public:
Player player1;
Player player2;
int matchNumber;
}; // end of Matches class
//1 fucntion as
Player* newPlayerArray;
newPlayerArray = new Player [partNumber];
newPlayerArray = general.createMatches1(pla yerArray, partNumber);
this function works fine and returns newPlayerArray correctly - players having names, ids and rankings. But when i try the function setmatches1, taking in the same array as before:
class General {
public:
General(){
}
~General(){
}
Player* createMatches1(Player *playerArray, int number);
Match* setMatches1(Match* matchArray, Player* playerArray);
}; // end of general class
//The METHOD
Match* General::setMatches1(Match * matchArray, Player* playerArray){
int y=0;
for (int x=0; x<partNumber; x+=2){
matchArray[y].player1 = playerArray[x];
matchArray[y].player2 = playerArray[x+1];
matchArray[y].matchNumber = y+1;
y++;
}
return matchArray;
}
called in main as:
matchArray = new Match [partNumber/2];
matchArray = general.setMatches1(matchA rray, newPlayerArray);
The matchArray now has match objects with players with ids and rankings FINE , but for some reason the names of the players DO NOT EXIST. they existed in the playerarray. I cannot se how just the names can be lost from the player element?
I would be very grateful if someone knows how to solve this problem.
Thanks
Ant
class Match{
public:
Player player1;
Player player2;
int matchNumber;
}; // end of Matches class
//1 fucntion as
Player* newPlayerArray;
newPlayerArray = new Player [partNumber];
newPlayerArray = general.createMatches1(pla
this function works fine and returns newPlayerArray correctly - players having names, ids and rankings. But when i try the function setmatches1, taking in the same array as before:
class General {
public:
General(){
}
~General(){
}
Player* createMatches1(Player *playerArray, int number);
Match* setMatches1(Match* matchArray, Player* playerArray);
}; // end of general class
//The METHOD
Match* General::setMatches1(Match
int y=0;
for (int x=0; x<partNumber; x+=2){
matchArray[y].player1 = playerArray[x];
matchArray[y].player2 = playerArray[x+1];
matchArray[y].matchNumber = y+1;
y++;
}
return matchArray;
}
called in main as:
matchArray = new Match [partNumber/2];
matchArray = general.setMatches1(matchA
The matchArray now has match objects with players with ids and rankings FINE , but for some reason the names of the players DO NOT EXIST. they existed in the playerarray. I cannot se how just the names can be lost from the player element?
I would be very grateful if someone knows how to solve this problem.
Thanks
Ant
At least this code is problematic:
>Player* newPlayerArray;
>newPlayerArray = new Player [partNumber];
>newPlayerArray = general.createMatches1(pla yerArray, partNumber);
the new created 'newPlayerArray' is replaced by the returned
pointer from 'createMatches1' which is different from newPlayerArray so this will lead to memory-leaks.
anyway I can't see the sense of returning the passed pointer
back to the calling function ... why not simply implement it
like i.e.:
void General::setMatches1(Match * matchArray, Player* playerArray)
{
int y=0;
for (int x=0; x<partNumber; x+=2){
matchArray[y].player1 = playerArray[x];
matchArray[y].player2 = playerArray[x+1];
matchArray[y].matchNumber = y+1;
y++;
}
}
...
matchArray = new Match [partNumber/2];
general.setMatches1(matchA rray, newPlayerArray);
...
ZOPPO
>Player* newPlayerArray;
>newPlayerArray = new Player [partNumber];
>newPlayerArray = general.createMatches1(pla
the new created 'newPlayerArray' is replaced by the returned
pointer from 'createMatches1' which is different from newPlayerArray so this will lead to memory-leaks.
anyway I can't see the sense of returning the passed pointer
back to the calling function ... why not simply implement it
like i.e.:
void General::setMatches1(Match
{
int y=0;
for (int x=0; x<partNumber; x+=2){
matchArray[y].player1 = playerArray[x];
matchArray[y].player2 = playerArray[x+1];
matchArray[y].matchNumber = y+1;
y++;
}
}
...
matchArray = new Match [partNumber/2];
general.setMatches1(matchA
...
ZOPPO
There are several problems here.
For one thing the match contain actual player objects instead of pointers or references to them. This means that the match object is supposed to have a copy of each player object participating in that match. If you modify the player data in the match it will not show up in the plain array of players and if you modify data in the player array it will not show up in the match data.
Another problem is that you have removed lots of the code, some of the functions appear with only body and with the parameters and function names removed. This is typically very important information and so we are unable to tell what is going on.
Another problem is that you indicate specifically that one of hte problems is that one of the elements of the player object which is having problems (the name element) but you do not give the source code for the player class anywhere. Instead you give us lots of other code which without the definitions and declarations of the player class won't really have any informational value.
Please post your code and question again.
Alf
For one thing the match contain actual player objects instead of pointers or references to them. This means that the match object is supposed to have a copy of each player object participating in that match. If you modify the player data in the match it will not show up in the plain array of players and if you modify data in the player array it will not show up in the match data.
Another problem is that you have removed lots of the code, some of the functions appear with only body and with the parameters and function names removed. This is typically very important information and so we are unable to tell what is going on.
Another problem is that you indicate specifically that one of hte problems is that one of the elements of the player object which is having problems (the name element) but you do not give the source code for the player class anywhere. Instead you give us lots of other code which without the definitions and declarations of the player class won't really have any informational value.
Please post your code and question again.
Alf
Salte is correct that you really need to post the Player code. But if I might hazard a guess, I'm guessing that the assignment operator for Player isn't handling the names correctly. Most probably, you're using the default assignment operator, and you have a field that doesn't copy correctly this way.
Gary
Gary
ASKER
Here is all the code . Thanks for the help guys
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fstream.h>
#include <iostream.h>
#include <iomanip.h>
int partNumber;
double noRounds;
class Player {
public:
char id[3];
char* name;
char* ranking;
int intRanking;
Player() {
name = 0;
ranking = 0;
intRanking =0;
}
~Player() {
if (id) delete [] id;
if (name) delete [] name;
if (ranking) delete [] ranking;
}
void setDetails (char *array);
void setIds(char *ids, int startPos);
void convertRanking(char* ranking);
void resetName(Player player, Player* playerArray);
}; //end of player class
////////////////////////// ////Player functions///////////////// ////////// ////////// ///////
void Player::setDetails (char *array) {
//set the name of the player
char tmpNameArray[13];
int n=3;
int y =0;
while(array[n] != ' '){
tmpNameArray[y] = array[n];
y++;
n++;
} // end of the do while loop
tmpNameArray[y] = '\0';
name = new char[strlen(tmpNameArray)] ;
//set the players ranking
char tmpRankingArray[5];
int z=0;
for (n; n<strlen(array); n++){
if (array[n] != ' '){
tmpRankingArray [z]= array[n];
z++;
}
}
tmpRankingArray[z] = '\0';
ranking = new char [strlen(tmpRankingArray)];
strcpy(name, tmpNameArray);
strcpy(ranking, tmpRankingArray);
}//end of set details
void Player::setIds(char *ids, int startPos){
id[0] = ids[startPos];
id[1] = ids[startPos+1];
id[2] = '\0';
}// end of setIds
void Player::convertRanking(cha r* ranking){
for (int x=0; x < partNumber; x++){
char * ch;
intRanking = int(strtod (ranking, &ch));
}
} // end of convert ranking
void Player::resetName(Player player, Player *playerArray){
cout << player.name;
cout << playerArray[1].name;
}
////////////////////////// Matches class///////////////////// ////////// //////////
class Match{
public:
Player player1;
Player player2;
int matchNumber;
}; // end of Matches class
////////////////////////// /////Match Functions///////////////// ////////// ////////// ////////// /////////
////////////////////////// ////////// ////////// ////////// General class///////////////////// ////////// ///////
class General {
public:
General(){
}
~General(){
}
void participantsCount(int &count);
char* removeSpaces(char *text);
void sortRank(Player *playerArray);
Player* createMatches1(Player *playerArray, int number);
Match* setMatches1(Match* matchArray, Player* playerArray);
void createTheTree(Player* playerArray, Match* matchArray);
}; // end of general class
////////////////////////// ////////// ////////Ge neral Class Functions///////////////// ////////// ////////// ////////// /////
//Count the number of participants function
void General::participantsCount (int &count) {
ifstream partStream ("participants.dat");
while (!partStream.eof()){
//remove first line
partStream.ignore(50, '\n');
//remove the second line
partStream.ignore(50, '\n');
while (!partStream.eof()){
char ch;
partStream.get(ch);
if (ch == ' '){
count++;
}
}
}
} // end of participants count
//remove the first 2 spaces from each line
char* General::removeSpaces(char *text){
int x;
do {
for (x = 0; x < strlen(text); x++){
text[x] = text[x+1];
}
text[strlen(text)] = '\0';
}while (text[0] == ' ');
return text;
}
void General::sortRank (Player *playerArray){
int a,b;
Player temp;
for ( b = 0; b < partNumber - 1; b++){
for (a = 0; a < partNumber - 1; a++){
if (playerArray[a].intRanking < playerArray[a+1].intRankin g){
temp = playerArray[a];
playerArray[a] = playerArray[a+1];
playerArray[a+1] = temp;
}
}
}
} // end of sort Players by rank
Player* General::createMatches1(Pl ayer *playerArray, int number) {
Player odds[number/2], evens[number/2];
Player * temp1;
Player * temp2;
if (number == 2) {
return playerArray;
} else {
for (int n = 0; n < number-1; n+=2) {
evens[n/2] = playerArray[n];
} // end for
for (int n = 1; n <= number-1; n+=2) {
odds[n/2] = playerArray[n];
} // end for
temp1 = createMatches1(evens, number/2);
temp2 = createMatches1(odds, number/2);
}
for (int n = 0; n < number/2; n++){
playerArray[n] = temp1[n];
}
for (int n = number/2; n < number; n++) {
playerArray[n] = temp2[n-(number/2)];
}
return playerArray;
} // end function create matches 1
Match* General::setMatches1(Match * matchArray, Player* playerArray){
int y=0;
for (int x=0; x<partNumber; x+=2){
matchArray[y].player1 = playerArray[x];
matchArray[y].player2 = playerArray[x+1];
matchArray[y].matchNumber = y+1;
y++;
}
return matchArray;
}// end of setMatches
void General::createTheTree(Pla yer* playerArray, Match* matchArray){
double numberR = noRounds;
int numberM = partNumber/2;
ofstream treeDat("tree.dat");
ofstream treeHtml("tree.html");
treeDat << "Matches for round 1" << endl;
treeDat << endl;
treeHtml << endl;
treeHtml << endl;
for (int x=0; x <numberR; x++){
treeHtml << "<table border = 1>" << "<caption align = top><font color=red>" <<"Round " << x << "</font>" << endl;
for (int x=0; x <numberM; x++){
treeDat << "Match" << setw(3) << matchArray[x].matchNumber <<": " <<"Player: " << setw(3) << matchArray[x].player1.id << " will play" << setw(3) << matchArray[x].player2.id << endl;
treeHtml << "<tr>" "<td>"<< "<font color=blue>" << "Match " << "</font>" << matchArray[x].matchNumber << ": " << "</font>" << "Player: " << matchArray[x].player1.id << " will play" << setw(3) << matchArray[x].player2.id << "</td></tr>" << endl
<< "</table>";
}// end of outputting matches
} // end of outputting rounds
} // end of create the tree
////////////////////////// ////////// ////////// //////MAIN ////////// ////////// ////////// ////////// /
int main(){
General general;
int count = 0;
general.participantsCount( count);
partNumber = count -2;
noRounds = sqrt(partNumber);
Player player; //player
Player *playerArray;
Match match; //match
Match *matchArray;
//////////EXTRACT PARTICIPANTS////////////
int arrayLength = (partNumber * 3) +1;
char *firstCharArray;
char *participantsArray; //IDs of partcipants
ifstream partStream ("participants.dat");
playerArray = new Player [partNumber];
while (!partStream.eof()){
//remove first line
partStream.ignore(100, '\n');
//remove the second line
partStream.ignore(100, '\n');
// extract the the third line
firstCharArray = new char[arrayLength];
partStream.getline(firstCh arArray, 100, '\n');
participantsArray = firstCharArray;
delete [] firstCharArray;
break;
//ignore the fourth line
partStream.ignore(100, '\n');
}
partStream.close(); // close the file
//remove spaces from participants
char IDs [(partNumber*2) + 1];
IDs[0] = *(participantsArray);
IDs[1] = *(participantsArray +1);
//int z=2;
int y=2;
for (int x =2; x < arrayLength; x++){
if (*(participantsArray + x) == ' '){
}else{
IDs[y] = *(participantsArray + x);
y++;
}
}
delete [] participantsArray;
IDs[(partNumber*2)] = '\0';
// create player struct variable IDS.
int x=0;
for (int n = 0; n < strlen(IDs); n+=2) {
player.setIds(IDs, n);
playerArray[x] = player;
x++;
}
///////////////////////EXT RACT players.dat/////////
ifstream playerStream ("players.dat");
char lineArray[30];
char *secondCharArray;
secondCharArray = lineArray;
int currentPlayer=0;
while (!playerStream.eof()){
playerStream.getline(secon dCharArray , 100, '\n');
if (secondCharArray[0] != '/' && secondCharArray[1] != '/'){
general.removeSpaces(secon dCharArray );
if (secondCharArray[0] == playerArray[currentPlayer] .id[0] && secondCharArray[1] == playerArray[currentPlayer] .id[1]){
playerArray[currentPlayer] .setDetail s(secondCh arArray);
currentPlayer++;
}
}
} // end of reading in the file
playerStream.close();
//set all the rankings to integers
for (int x=0; x <partNumber; x++){
playerArray[x].convertRank ing(player Array[x].r anking);
}
//sort players in descending order
general.sortRank(playerArr ay);
//produce round 1
Player* newPlayerArray;
newPlayerArray = new Player [partNumber];
newPlayerArray = general.createMatches1(pla yerArray, partNumber);
for (int x=0; x <partNumber; x++){
//cout << newPlayerArray[x].name;
}
//set the matches
matchArray = new Match [partNumber/2];
matchArray = general.setMatches1(matchA rray, newPlayerArray);
for(int x=0; x < partNumber/2; x++){
cout << matchArray[x].player1.id;
}
general.createTheTree(newP layerArray , matchArray);
return 0;
}
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fstream.h>
#include <iostream.h>
#include <iomanip.h>
int partNumber;
double noRounds;
class Player {
public:
char id[3];
char* name;
char* ranking;
int intRanking;
Player() {
name = 0;
ranking = 0;
intRanking =0;
}
~Player() {
if (id) delete [] id;
if (name) delete [] name;
if (ranking) delete [] ranking;
}
void setDetails (char *array);
void setIds(char *ids, int startPos);
void convertRanking(char* ranking);
void resetName(Player player, Player* playerArray);
}; //end of player class
//////////////////////////
void Player::setDetails (char *array) {
//set the name of the player
char tmpNameArray[13];
int n=3;
int y =0;
while(array[n] != ' '){
tmpNameArray[y] = array[n];
y++;
n++;
} // end of the do while loop
tmpNameArray[y] = '\0';
name = new char[strlen(tmpNameArray)]
//set the players ranking
char tmpRankingArray[5];
int z=0;
for (n; n<strlen(array); n++){
if (array[n] != ' '){
tmpRankingArray [z]= array[n];
z++;
}
}
tmpRankingArray[z] = '\0';
ranking = new char [strlen(tmpRankingArray)];
strcpy(name, tmpNameArray);
strcpy(ranking, tmpRankingArray);
}//end of set details
void Player::setIds(char *ids, int startPos){
id[0] = ids[startPos];
id[1] = ids[startPos+1];
id[2] = '\0';
}// end of setIds
void Player::convertRanking(cha
for (int x=0; x < partNumber; x++){
char * ch;
intRanking = int(strtod (ranking, &ch));
}
} // end of convert ranking
void Player::resetName(Player player, Player *playerArray){
cout << player.name;
cout << playerArray[1].name;
}
//////////////////////////
class Match{
public:
Player player1;
Player player2;
int matchNumber;
}; // end of Matches class
//////////////////////////
//////////////////////////
class General {
public:
General(){
}
~General(){
}
void participantsCount(int &count);
char* removeSpaces(char *text);
void sortRank(Player *playerArray);
Player* createMatches1(Player *playerArray, int number);
Match* setMatches1(Match* matchArray, Player* playerArray);
void createTheTree(Player* playerArray, Match* matchArray);
}; // end of general class
//////////////////////////
//Count the number of participants function
void General::participantsCount
ifstream partStream ("participants.dat");
while (!partStream.eof()){
//remove first line
partStream.ignore(50, '\n');
//remove the second line
partStream.ignore(50, '\n');
while (!partStream.eof()){
char ch;
partStream.get(ch);
if (ch == ' '){
count++;
}
}
}
} // end of participants count
//remove the first 2 spaces from each line
char* General::removeSpaces(char
int x;
do {
for (x = 0; x < strlen(text); x++){
text[x] = text[x+1];
}
text[strlen(text)] = '\0';
}while (text[0] == ' ');
return text;
}
void General::sortRank (Player *playerArray){
int a,b;
Player temp;
for ( b = 0; b < partNumber - 1; b++){
for (a = 0; a < partNumber - 1; a++){
if (playerArray[a].intRanking
temp = playerArray[a];
playerArray[a] = playerArray[a+1];
playerArray[a+1] = temp;
}
}
}
} // end of sort Players by rank
Player* General::createMatches1(Pl
Player odds[number/2], evens[number/2];
Player * temp1;
Player * temp2;
if (number == 2) {
return playerArray;
} else {
for (int n = 0; n < number-1; n+=2) {
evens[n/2] = playerArray[n];
} // end for
for (int n = 1; n <= number-1; n+=2) {
odds[n/2] = playerArray[n];
} // end for
temp1 = createMatches1(evens, number/2);
temp2 = createMatches1(odds, number/2);
}
for (int n = 0; n < number/2; n++){
playerArray[n] = temp1[n];
}
for (int n = number/2; n < number; n++) {
playerArray[n] = temp2[n-(number/2)];
}
return playerArray;
} // end function create matches 1
Match* General::setMatches1(Match
int y=0;
for (int x=0; x<partNumber; x+=2){
matchArray[y].player1 = playerArray[x];
matchArray[y].player2 = playerArray[x+1];
matchArray[y].matchNumber = y+1;
y++;
}
return matchArray;
}// end of setMatches
void General::createTheTree(Pla
double numberR = noRounds;
int numberM = partNumber/2;
ofstream treeDat("tree.dat");
ofstream treeHtml("tree.html");
treeDat << "Matches for round 1" << endl;
treeDat << endl;
treeHtml << endl;
treeHtml << endl;
for (int x=0; x <numberR; x++){
treeHtml << "<table border = 1>" << "<caption align = top><font color=red>" <<"Round " << x << "</font>" << endl;
for (int x=0; x <numberM; x++){
treeDat << "Match" << setw(3) << matchArray[x].matchNumber <<": " <<"Player: " << setw(3) << matchArray[x].player1.id << " will play" << setw(3) << matchArray[x].player2.id << endl;
treeHtml << "<tr>" "<td>"<< "<font color=blue>" << "Match " << "</font>" << matchArray[x].matchNumber << ": " << "</font>" << "Player: " << matchArray[x].player1.id << " will play" << setw(3) << matchArray[x].player2.id << "</td></tr>" << endl
<< "</table>";
}// end of outputting matches
} // end of outputting rounds
} // end of create the tree
//////////////////////////
int main(){
General general;
int count = 0;
general.participantsCount(
partNumber = count -2;
noRounds = sqrt(partNumber);
Player player; //player
Player *playerArray;
Match match; //match
Match *matchArray;
//////////EXTRACT PARTICIPANTS////////////
int arrayLength = (partNumber * 3) +1;
char *firstCharArray;
char *participantsArray; //IDs of partcipants
ifstream partStream ("participants.dat");
playerArray = new Player [partNumber];
while (!partStream.eof()){
//remove first line
partStream.ignore(100, '\n');
//remove the second line
partStream.ignore(100, '\n');
// extract the the third line
firstCharArray = new char[arrayLength];
partStream.getline(firstCh
participantsArray = firstCharArray;
delete [] firstCharArray;
break;
//ignore the fourth line
partStream.ignore(100, '\n');
}
partStream.close(); // close the file
//remove spaces from participants
char IDs [(partNumber*2) + 1];
IDs[0] = *(participantsArray);
IDs[1] = *(participantsArray +1);
//int z=2;
int y=2;
for (int x =2; x < arrayLength; x++){
if (*(participantsArray + x) == ' '){
}else{
IDs[y] = *(participantsArray + x);
y++;
}
}
delete [] participantsArray;
IDs[(partNumber*2)] = '\0';
// create player struct variable IDS.
int x=0;
for (int n = 0; n < strlen(IDs); n+=2) {
player.setIds(IDs, n);
playerArray[x] = player;
x++;
}
///////////////////////EXT
ifstream playerStream ("players.dat");
char lineArray[30];
char *secondCharArray;
secondCharArray = lineArray;
int currentPlayer=0;
while (!playerStream.eof()){
playerStream.getline(secon
if (secondCharArray[0] != '/' && secondCharArray[1] != '/'){
general.removeSpaces(secon
if (secondCharArray[0] == playerArray[currentPlayer]
playerArray[currentPlayer]
currentPlayer++;
}
}
} // end of reading in the file
playerStream.close();
//set all the rankings to integers
for (int x=0; x <partNumber; x++){
playerArray[x].convertRank
}
//sort players in descending order
general.sortRank(playerArr
//produce round 1
Player* newPlayerArray;
newPlayerArray = new Player [partNumber];
newPlayerArray = general.createMatches1(pla
for (int x=0; x <partNumber; x++){
//cout << newPlayerArray[x].name;
}
//set the matches
matchArray = new Match [partNumber/2];
matchArray = general.setMatches1(matchA
for(int x=0; x < partNumber/2; x++){
cout << matchArray[x].player1.id;
}
general.createTheTree(newP
return 0;
}
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
>> if (id) delete [] id;
Don't do it.... id[] has been defined as an array, not as a pointer. Its not been allocated memory using new, so the delete[] is not needed.
Man, your code is too long to debug but all that I would like to say is that whenever you're using pointer data-members in a class, with a destructor having 'delete' statements, then you should be a little careful while passing objects as arguments. You should never pass them by value, as then, a new object is instantiated (the formal argument in the called function), the values of the data-members are copied (including the pointer data-members), so the pointer data-member of the formal argument in the callED function points to the same location as the actual argument in the callING function, and when this called function finishes execution, the destructor is called for the formal argument which deallocates the memory because of the 'delete' statements, and thus, the actual argument's pointer data-member (in the callING function) is now also pointing to garbage.
Hope that you got that, and its of help to you!
Mayank.
Don't do it.... id[] has been defined as an array, not as a pointer. Its not been allocated memory using new, so the delete[] is not needed.
Man, your code is too long to debug but all that I would like to say is that whenever you're using pointer data-members in a class, with a destructor having 'delete' statements, then you should be a little careful while passing objects as arguments. You should never pass them by value, as then, a new object is instantiated (the formal argument in the called function), the values of the data-members are copied (including the pointer data-members), so the pointer data-member of the formal argument in the callED function points to the same location as the actual argument in the callING function, and when this called function finishes execution, the destructor is called for the formal argument which deallocates the memory because of the 'delete' statements, and thus, the actual argument's pointer data-member (in the callING function) is now also pointing to garbage.
Hope that you got that, and its of help to you!
Mayank.
Alf, just refer to this:
https://www.experts-exchange.com/questions/20562641/Passing-an-array-to-funciton-part-of-the-array-object-is-lost.html
The code's exactly the same, though the questioner is different..
Mayank.
https://www.experts-exchange.com/questions/20562641/Passing-an-array-to-funciton-part-of-the-array-object-is-lost.html
The code's exactly the same, though the questioner is different..
Mayank.
Mayank,
Hmmm... dare we say the h word?
Seeing that the code is so similar I'd guess that the majority of the code is from the teacher and so they really get it handed for free.
Man, they need to shape up :-)
Alf
Hmmm... dare we say the h word?
Seeing that the code is so similar I'd guess that the majority of the code is from the teacher and so they really get it handed for free.
Man, they need to shape up :-)
Alf
:-)
Or maybe from a friend who is good at C++ and distributes his code to friends, but is not good enough to always give them the correct code.
Mayank.
Mayank.
Thanks,