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

Posted on 2003-03-17
Medium Priority
Last Modified: 2010-05-18
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];
     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];
     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] != '/'){
if (secondCharArray[0] == idPlayerArray[currentPlayer].id[0] && secondCharArray[1] ==   idPlayerArray[currentPlayer].id[1]){          
         setDetails(idPlayerArray[currentPlayer], secondCharArray);
      playerArray[currentPlayer] = idPlayerArray[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.

Question by:antos
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
LVL 15

Expert Comment

ID: 8154936
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.

LVL 46

Expert Comment

by:Kent Olsen
ID: 8154939

It's also posted in another thread.


Accepted Solution

GregToombs earned 300 total points
ID: 8155385
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.

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

LVL 30

Expert Comment

by:Mayank S
ID: 8157425
>> 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;


strcpy ( player.name, tmpNameArray ) ;

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


Author Comment

ID: 8158259
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.

LVL 30

Expert Comment

by:Mayank S
ID: 9505737
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.


Featured Post

On Demand Webinar: Networking for the Cloud Era

Did you know SD-WANs can improve network connectivity? Check out this webinar to learn how an SD-WAN simplified, one-click tool can help you migrate and manage data in the cloud.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Written by John Humphreys C++ Threading and the POSIX Library This article will cover the basic information that you need to know in order to make use of the POSIX threading library available for C and C++ on UNIX and most Linux systems.   [s…
This article will show you some of the more useful Standard Template Library (STL) algorithms through the use of working examples.  You will learn about how these algorithms fit into the STL architecture, how they work with STL containers, and why t…
The viewer will learn how to use the return statement in functions in C++. The video will also teach the user how to pass data to a function and have the function return data back for further processing.
The viewer will learn how to clear a vector as well as how to detect empty vectors in C++.
Suggested Courses

770 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question