Pass array of pointers to a function

Pages: 12
OK this 'may' not sound a newbie question but I probably won't understand the answer as i'm new to all this. I've cut bits of of my (monopoly game) program to illustrate the point. I have a header file with a class defined called PlayerClass. In main() I dynamically allocate an array of pointers called pAllPlayerClass, this works great and I can access class members no problem, e.g. change the name of a player (m_strPlayerName ).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
  class PlayerClass{
        public:
        string m_strPlayerName;};

  int main(){

    PlayerClass* pAllPlayerClass = new PlayerClass[nPlayers];
 
    int i=1;
    string strPlayerName;	
    cin>>strPlayerName;
    pAllPlayerClass[i].m_strPlayerName = strPlayerName;  //this works ok

  } 


I have a pointer, also dynamically allocated, but not an array called pTileData which looks in another header file for game board information. This pointer behaves whilst inside main and when passed to other functions, such as BuyProperties

1
2
3
4
5
6
7
8
9
10
11
12
13
14

  int BuyProperties(int tile, int i, PlayerClass pAllPlayerClass, TileData pTileData){
    group = pTileData.m_nGroup[tile];                                   //this works ok
    cout<<"Your name is "<<pAllPlayerClass[i].m_strPlayerName<<endl;	//why doesn't this work?
  }

{
  int main(){

    TileData* pTileData = new TileData;

    BuyProperties(tile, i, pAllPlayerClass, pTileData);	

  }


However, when accessing pAllPlayerClass inside BuyProperties next to the "why doesn't this work?" comment I get a compile error:

>BuyProperties.cpp(11): error C2676: binary '[' : 'PlayerClass' does not define this operator or a conversion to a type acceptable to the predefined operator


Am I passing the pointer incorrectly as it seems to be OK with other pointers and values seem to change as expected in run-time? Or is there special 'handling' for an array of pointers? Is ther a better way of doing this?

Your collective experience is very much appreciated! Thank you in advance.
The issue is that your function takes a PlayerClass, not a pointer to one.

drPek wrote:
1
2
3
4
5
6
    PlayerClass* pAllPlayerClass = new PlayerClass[nPlayers];
 
    int i=1;
    string strPlayerName;	
    cin>>strPlayerName;
    pAllPlayerClass[i].m_strPlayerName = strPlayerName;  //this works ok 
I'm assuming you meant i=0 and not i=1, otherwise you're corrupting memory when there is one player. Then again there shouldn't be only 1 player, but I still hope you know to start from 0 and end at count-1.
Last edited on
Excuse me, but if I may disturb:

Would you explain to me, vlad, why do you consider syntax Class* Object
worse then Class *Object?

Personally, I prefer the first one, because it clearly shows me the type - if I see Class, I know it's object of Class. If I see Class*, I know it's pointer to Class. If I see Class**&, I will be able to translate it accordingly.

And even if it has some sense, please, next time provide us with explanation instead of calling names. It's just not polite.
His only non-stylistic argument is that

int* a, b;

declares a pointer to an integer and an integer, respectively.
MatthewRock


As you see from the original post the author though that he allocated an array of pointers by this statement

PlayerClass* pAllPlayerClass = new PlayerClass[nPlayers];

He would not do such mistake if he would write correctly

PlayerClass *pAllPlayerClass = new PlayerClass[nPlayers];

The original record only confuses readers. Consider the following code

for ( int* first = a, last = a + N; ++first ) { /* some code *? }

If to think as you think when this code is valid because as you wrote int* is a type. However this code is invalid. variable last has no the type int*.

The problem is that record contradicts the C++ grammar where there is a clear difference between type specifiers and declarators. So You invented (more precisely you simply follow some idiots without critical analyse) record that simply confuses readers, makes it harder to understand the grammar of C++.
Last edited on
Also I would like to append that now int* and int * have different meaning in the field of programming languages. For example in C# this record

int* a, b;

indeed means that two pointers are declared.

So you should have a general programming culture and do not mess idioms.
Maybe instead of memorizing inconsistencies in programming languages you should avoid using the comma like that as suggested in other threads ;)
Last edited on
Well, I do not understand your for loop condition:

last = a + n;

edit:
oh now I can see, there is a comma there. Well, first of all - your for loop syntax is bad, which mislead me. Secondly, I know that is the case in C++(wish it was like in your 2nd post) - but declaring pointers like that is just bad, imho. It is error-prone, and most of the time, when you create pointers, you either use them instantly, or set them to nullptr. So I guess from all these examples, the best practice would be:

1
2
int* x = nullptr;
int *y = nullptr;


instead of

 
int *x = nullptr, *y = nullptr;

Second one is more ugly. If you like to look at these things, try this:
http://www.programmerinterview.com/index.php/c-cplusplus/c-declarations/
:)

And in your example, defining first as

int *first

wouldn't change anything. If someone is unable to see what type is he using, then it's something wrong with him, not his syntax.

And again, if he allocates some memory using operator new, he didn't make a mistake of using wrong syntax with * - as it doesn't matter at this point - but he made a mistake later:

new PlayerClass[nPlayers];

Here we can see an array of PlayerClass. If he used

new PlayerClass*[nPlayers];

that would be it.

And now I would like you to notice, that here he is using the same syntax as I talked about - with asterisk next to name, rather than variable.

And last of all:
You can declare functions using only types(and provide their names in definition), like this:

void someFunct(int*, int*&, char**&);
1
2
3
4
5
6
//code...

void someFunct(int* name1, int*& name2, char**& name3)
{
//code...
}


Because type is int*, not int. I think, that using your convention can be distracting for newbies. Also, when they got compiler error, they may wonder about what that type is, as compiler is using "my" method.

PS.
But of course it's all in purpose of simplifying code reading, and one may find any of these easier.
Last edited on
@MatthewRock

//code...

void someFunct(int* name1, int*& name2, char**& name3)
{
//code...
}


It is very bad record. Ask any beginner what does int*& mean and he will not answer. It would be much better to write

//code...

void someFunct(int *name1, int * &name2, char ** &name3)
{
//code...
}
Last edited on
@vlad from moscow
Give it a rest. Are you striving to be the first one on the forums to be banned for pointless insults?

Yes, syntax wise it is better to use int *p; instead of int* p, but you never even bothered telling why. Instead you started talking about C# when we are talking about C++. Instead of insulting users for poor syntax, why not use the chance to educate them on why instead of tearing them down.

Educate: If you are using int*, which is a bad choice and you decide to make (lets say 3 pointers, and I'm not going to bother initializing them in this example) you usually add a bug or error into your code.
 
int* a, b, c; // makes variable a  a pointer, but just makes b and c regular ints 


If you get into the habit of doing int *p you are less likely to do that error.
 
int *a, *b, *c; // all three variables are now pointers 


No one is perfect though, no matter what vlad wants people to think. Even using the preferred method, we are only human, and you can still mess up.
Last edited on by closed account z6A9GNh0
@BHXSpecter

Instead you started talking about C# when we are talking about C++.


As all beginners you even do not understand that there is a general culture in programming. So you do not take into account general idioms of other languages.

It is you who talks only about C++. As for me I am talkink about the general culture in programming.
Last edited on
If you will follow the grammar of the language it will help you to understand the language deeply. If you will use constructions that contradict the description of the grammar you will only confuse others.
Last edited on
vlad from moscow wrote:
As all beginners you even do not understand that there is a general culture in programming. So you do not take into account general idioms of other languages.

It is you who talks only about C++. As for me I am talkink about the general culture in programming.


Beginner? I've been programming for 17 years and am well versed in several programming languages.

So not only did you insult them, but you also are derailing the thread with your ramble about general culture in programming.

So why are you here if you don't want to help beginners? Seems all you get off on is insulting them and making them feel small to make yourself feel bigger.
@BHXSpecter
So why are you here if you don't want to help beginners?


I am sorry. Next time I will help you.:)
Now wait a minute. Help me? o.O Okay, I'll take that help.
Thank you to L B and others for your help and to Vlad for your helpful, colourful and off-beat comments!

I learnt that it does not matter which side the * goes to but I take Vlad's point that it can be confusing when using the pointer elsewhere in the program and trip people up as demonstrated.

So why does my pointer pAllPlayerClass still access the member variables of the object when called inside main() if I have writing the pointer syntax incorrectly all this time? i.e. inside main() I have...

1
2
cout<<pAllPlayerClass[i].m_strPlayerName<<" has a cash balance of "
<<GBP<<pAllPlayerClass[i].m_nCash<<endl;


which works but when I use the following syntax

1
2
cout<<*pAllPlayerClass[i].m_strPlayerName<<" has a cash balance of "
<<GBP<<*pAllPlayerClass[i].m_nCash<<endl;


I get a compile error:
1>GC01.cpp(80): error C2100: illegal indirection
Remove '*' before pAllPlayerClass

cout<<pAllPlayerClass[i].m_strPlayerName<<" has a cash balance of "
<<GBP<<pAllPlayerClass[i].m_nCash<<endl;
now when I access the member variable inside the called function and compile i get:

1>RentCharge.cpp(68): error C2228: left of '.m_nGroup' must have class/struct/union

and it suggests using -> operator to access the class member. This stops the compile error but is it the correct way to program?

1
2
3
4

group = pTileData.m_nGroup[tile];     //change this
group = pTileData->m_nGroup[tile];   //to this?


The compiler is also complainging about the function:

1>GC01.cpp(337): error C2664: 'RentCharge' : cannot convert parameter 4 from 'TileData' to 'TileData *'

1
2
3
4

rent = RentCharge(tile,owner,move,*pTileData);    //the function 
int RentCharge(int,int,int,TileData*);    //the function prototype


Any ideas?

thanks for your input, appreciated!
drPek wrote:
1
2
rent = RentCharge(tile,owner,move,*pTileData);    //the function 
int RentCharge(int,int,int,TileData*);    //the function prototype 
I see something wrong here.
Which is? You said that "The issue is that your function takes a PlayerClass, not a pointer to one." so shouldn't the function prototype be told to take a pointer to type TileData?

Sorry, still very confused!
Pages: 12