Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 238
  • Last Modified:

c++ assigning array values - included setDetails method()

hi.
I have struct declared as:

struct Player {
    char id[3];
    char *name;
    char *ranking;
    double doubleRanking;
};

I have an arrary of structs called playerArray.
setDeatils method as:

void setDetails (Player &player, char array[]) {
     //player.id = id;
 
     //set the name of the player
     char tmpNameArray[13];
     int x=3;
     int y =0;

     for (x; x < strlen(array)-4; x++){
          if (array[x] != ' '){
               tmpNameArray[y] = array[x];
               y++;
          }
     }
     tmpNameArray[y] = '\0';

     player.name = tmpNameArray;

     //set the players ranking
     char tmpRankingArray[10];
     
     int z=0;
     for (x; x<strlen(array); x++){    
          if (array[x] != ' '){
               tmpRankingArray [z]= array[x];
               z++;
          }
     }
     tmpRankingArray[z] = '\0';
     player.ranking = tmpRankingArray;
     
}

//read in line and assgning array:

while (!playerStream.eof()){
         
playerStream.getline(secondCharArray, 100, '\n');
if (secondCharArray[0] != '/' && secondCharArray[1] != '/'){
    removeSpaces(secondCharArray);
if (secondCharArray[0] == idPlayerArray[currentPlayer].id[0] && secondCharArray[1] ==   idPlayerArray[currentPlayer].id[1]){          
         
         setDetails(idPlayerArray[currentPlayer], secondCharArray);
      playerArray[currentPlayer] = idPlayerArray[currentPlayer];
      currentPlayer++;
                   
                   
                   
}//end if checking if player is playing in this tournament
             
}//end if checking if the line has usefull infomation
         
}//end while

    for(int x=0 ; x < partNumber; x++){
      cout << playerArray[x].name << endl;
    }

the set details method changes the players values correctly, and then i wish to store this player idPlayerArray[currentPlayer] in my playerArray. However what is happenning is that every element of playerArray becomes == to the idPlayerArray[currentPlayer].

Therefore the last cout << produces all the same name!. I guess its always pointing to the same player location and not setting up new locations?.

How would i solve this problem???????, it has been baffling me for a while now.

Thanks you for your help.

Antos
0
antos
Asked:
antos
1 Solution
 
efnCommented:
Hi Antos,

I'll explain what I think your problem is for name, although exactly the same considerations apply to ranking.

You only have one place where you store names:  the  tmpNameArray array in the setDetails function.  Each time the program reads a record, it puts the name in this array, wiping out any previous name.  All the name pointers in Player structures point to this same place.  That's why when you put it out, you get the same data over and over.

To make it work, you should give each Player a name of its own, not have it point to the last one read.  To do this, use char arrays, not pointers, for the name and ranking fields, and in setDetails, copy the data into the array members.

This would also fix another potential bug which happens not to have bitten you, which is that it's not safe to use a pointer to tmpNameArray outside the setDetails function.  tmpNameArray has automatic duration, which means that after control leaves setDetails, tmpNameArray's memory could be reused for some other variable.

--efn
0
 
Kent OlsenData Warehouse Architect / DBACommented:

It's also posted in another thread.

Kdo
0
 
GregToombsCommented:
I think your problem is in string allocation.
When you wrote player.name = tmpNameArray, you didn't transfer a string. You simply set the pointer player.name equal to the pointer tmpNameArray. Since tmpNameArray is in a function, when it goes "out of scope" it gets unallocated. This is baaad, because now player.name points to a section in memory that has been unallocated.

Instead, what you have to do is change the "name" and "ranking" members from being character pointers to character buffers, as in

struct Player {
   char id[3];
   char name[32];
   char ranking[32];
   double doubleRanking;
}

it would make even more sense to change this structure into a class, so that your setDetails function could be a member of Player. Also you could have the buffers allocated dynamically. As in:

class Player {
   Player() {
      name = 0;
      ranking = 0;
   }
   ~Player() {
      if (name) delete [] name;
      if (ranking) delete [] ranking;
   }

   void setDetails(char array[]) {
      ...
      name = new char[strlen(array)];
      strcpy(name, array};
      ranking = new char[strlen(array)];
      strcpy(ranking, array);
      ...
   }

   char id[3];
   char* name;
   char* ranking;
   double doubleRanking;
};


Both examples are incomplete, but you must choose such a schema to allocate room for your structure strings.
0
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 
Mayank SAssociate Director - Product EngineeringCommented:
>> player.name = tmpNameArray;

When you're doing this, then you're assigning the pointer 'name' to point to the location allocated for tmpNameArray. Now, tmpNameArray is local to the setDetails () function, and so when that function finishes execution, then memory for all the variables local to it is deallocated and is again free. So, after the function-execution, your pointer 'name' is effectively pointing to a garbage location.

I suggest that you replace your pointer members by strings, as:

char name[10] ; // or what-ever range

And replace:

>> >> player.name = tmpNameArray;

by:

strcpy ( player.name, tmpNameArray ) ;

Of course, you need to include <string.h> for that.

Mayank.
0
 
antosAuthor Commented:
Thank you for your help. I understand the error now, used to JAVA language, so having trouble programming in c++. The player class is a good idea and has now been implemented. I can now continue with my program :-s.

Cheers
Antos
0
 
Mayank SAssociate Director - Product EngineeringCommented:
Yeah, but man, be a little careful while working with destructors. Since you don't have them in Java (since you're not bogged with the burden of memory de-allocation because the GREAT JVM does that for you), so be a little careful while using them in C. I hope that you have still gone through the other comments on this page and found them useful.

rgds,
Mayank.
0

Featured Post

Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say thank you for being a part of the community.

Tackle projects and never again get stuck behind a technical roadblock.
Join Now