• We’re currently investigating an issue related to the forum theme and styling that is impacting page layout and visual formatting. The problem has been identified, and we are actively working on a resolution. There is no impact to user data or functionality, this is strictly a front-end display issue. We’ll post an update once the fix has been deployed. Thanks for your patience while we get this sorted.

C++ why is this variable loosing it's scope?

Red Squirrel

No Lifer
This is my main function, the classes and such are most likely irrelevant in this case, so I won't post unless requested.


Half way through the program, the numberofplayers looses it's scope completely. Its just some random left over garbage in memory, even though it's global to main, and is set to 0, then changed by the user. Sometimes it's 3, sometimes it's 6, sometimes negative, etc... I've been breaking my head trying to figure out why it looses scope upon entering the while loop. as far as I know, it should keep it's scope even inside a loop, as it was declared before hand.

Code:
int main()
{
srand(time(0));//randomize seed




player players[7];
players[0].SetName("Dealer");
players[1].SetName("Player 1");
players[2].SetName("Player 2");
players[3].SetName("Player 3");
players[4].SetName("Player 4");
players[5].SetName("Player 5");
players[6].SetName("Player 6");



int numberofplayers=0;

do
{
cout<<"\nEnter number of players[1-6] #";
cin>>numberofplayers;
}while(numberofplayers<1 || numberofplayers>6);




int pot;
for(int i=1;i<=numberofplayers;i++)
{
pot=0;
    do
    {
    cout<<"Enter pot for "<<players[i].GetName()<<"# ";
    cin>>pot;
    }while(pot<1);
    
    players[i].SetPot(pot);    
    
}




deck mydeck;
card mycard;




char playagain='y';
while(playagain=='y')
{

mydeck.refill();
mydeck.shuffle();

cout<<"players reset";getch(); //------------------debug


//reset players
for(int i=0;i<=numberofplayers;i++)players[i].reset();

cout<<"deal";getch(); //------------------debug

    for(int i=0;(!mydeck.isempty() && i<2); i++)//deal 2 cards to each player
    {
        for(int ii=1;ii<=numberofplayers;ii++)
        {
        players[ii].ReceiveCard(mydeck.deal(true));
        }
    }

//dealer is different, as one card is flipped down
players[0].ReceiveCard(mydeck.deal(true));
players[0].ReceiveCard(mydeck.deal(false));

    


cout<<"\n\ntest:"<<numberofplayers<<"\n\n";


cout<<"bets";getch(); //------------------debug


//place bets
    for(int i=1;i<=numberofplayers;i++)
    {
    if(!players[i].playing)continue;
            
            
    int bet=0;
        do
        {
        cout<<"Enter bet for "<<players[i].GetName()<<" (max "<<players[i].GetPot()<<")# ";
        cin>>bet;
        }while((bet<1)||(bet>players[i].GetPot()));
    
    players[i].SetBet(bet);
    }


bool gameover=false;
int playershit;
int playersleft=numberofplayers;

while(!gameover)
{
system("cls");
playershit=0;





    //show all cards
    for(int i=0;i<=numberofplayers;i++)
    {
    if(!players[i].playing)continue;
    cout<<endl<<players[i].ShowHand()<<endl<<"Value: "<<players[i].gethandvalue();
    
    if(players[i].gethandvalue()>21)
    {
    cout<<" - BUSTED!";
    players[i].playing=false;
    playersleft--;
    }
    
    cout<<"\n\n--------------\n"; 
    }   


    //hit/stand
    for(int i=1;i<=numberofplayers;i++)
    {
    if(!players[i].playing)continue;
    char hs='0';
    cout<<"\n"<<players[i].GetName()<<": it or [s]tand?# ";
    cin>>hs;
        if(hs=='h')
        {players[i].ReceiveCard(mydeck.deal(true));
        playershit++; }
    }



if(playershit==0 || playersleft<=0)gameover=true;



players[0].flipnextcard();
if(players[0].gethandvalue()<15)players[0].ReceiveCard(mydeck.deal(true));
}


//determine winner:



player winner=players[0]; //automaticly assign dealer as winner by default
int winnerid=0;
//loop through players to find the one with highest score below 21
for(int i=1;i<=numberofplayers;i++)
{
    if ((players[i].gethandvalue()>winner.gethandvalue()) &&(players[i].gethandvalue()<=21))winner = players[i];
    {
    winnerid=i;
    }

}

cout<<"\n\n---------------------------\n\n"<<winner.GetName()<<" wins!\n"<<winner.ShowHand()<<"\nValue:"<<winner.gethandvalue()<<"\n";


//distribute funds
for(int i=0;i<=numberofplayers;i++)
{
if (i==winnerid)continue;
players[winnerid].WinBet(players[i].LooseBet());
}


cout<<"Would you like to play again(y/n)?";
do
{
playagain=getch();
}while (playagain!='y' && playagain!='n');
cout<<"\n\n\n";
}




    

    system("PAUSE");
    return 0;
}
 
I'm not gonna try reading that - try using the attach code feature next time.

But ... what I'm guessing is happening is that somewhere you are writing to bad memory ... an unallocated pointer, or past the end of an array, etc. Something like that. It's overwriting the memory allocated to numberofplayers
 
You never initialize your player array.

player players[7];

// Need this
for (int i = 0; i < 7; i++){
players[ i] = new player();
}

players[0].SetName("Dealer");
players[1].SetName("Player 1");
players[2].SetName("Player 2");
players[3].SetName("Player 3");
players[4].SetName("Player 4");
players[5].SetName("Player 5");
players[6].SetName("Player 6");
 
Originally posted by: MrChad
You never initialize your player array.

player players[7];

// Need this
for (int i = 0; i < 7; i++){
players[ i] = new player();
}

players[0].SetName("Dealer");
players[1].SetName("Player 1");
players[2].SetName("Player 2");
players[3].SetName("Player 3");
players[4].SetName("Player 4");
players[5].SetName("Player 5");
players[6].SetName("Player 6");

this is C++, objects are not references by default

anyway I agree with Armitage. it's probably stack corruption caused by invalid writes. I took a brief look and didn't find anything thing. the problem might be in the player class. since the program is fairly short, you can just keep the variable in watch and step through the code and see when it changes.
 
I get this error when I try to use the new keyword.

no match for 'operator=' in 'players = (((player*)operator new(668u)), (<anonymous>->player:😛layer(), <anonymous>))'

And yes there is a constructor declared for it, (two, actually - one that accepts an argument, one that does not)


Think that's a C# thing though, isin't it? I don't know C# outside of messing with runuo scripts though. I'll take a look around to see if I'm writing past the end of an array or that sort of thing.
 
Originally posted by: MrChad
You never initialize your player array.

player players[7];

// Need this
for (int i = 0; i < 7; i++){
players[ i] = new player();
}

Nope ... if there is a default constructor declared, these are already initialized. And players[n] is not a pointer, soyou can't assign "new player()" to it.

players[0].SetName("Dealer");
players[1].SetName("Player 1");
players[2].SetName("Player 2");
players[3].SetName("Player 3");
players[4].SetName("Player 4");
players[5].SetName("Player 5");
players[6].SetName("Player 6");

 
wow messing with the dev C++ debugger when I actually manage to make a watch show up (seems to not work well) I see some wacky things happen during execution. May be better off rewriting, this is too messed up. If I add another integer and never use it, it's value also changes throughout the program. I hardly use any arrays in my classes so the problem is not a buffer overflow or anything.

Then again, I don't even think the teacher bothers to test, he just looks at the code, so I may get away, but I'd hate to submit a program that does not even work properly.
 
I took a scan through it.

What bothers me is that he is referencing players (which is an array of classes) without defining the index.

Therefore who knows what type of indexing/corruption may be occuring.

example:


player players[7];

for (int i=1 ; i <= numberofplayers ; i++)
{
if (!players.playing) continue;
}

How does the code know which players object is being referenced?

Also, the next memory variable slot after players is numberofplayers.
It may be possible that the lack of proper indexing is causing memory overflow from players. into numberofplayers
 
Originally posted by: EagleKeeper
I took a scan through it.

What bothers me is that he is referencing players (which is an array of classes) without defining the index.

Therefore who knows what type of indexing/corruption may be occuring.

example:


player players[7];

for (int i=1 ; i <= numberofplayers ; i++)
{
if (!players.playing) continue;
}

How does the code know which players object is being referenced?

Also, the next memory variable slot after players is numberofplayers.
It may be possible that the lack of proper indexing is causing memory overflow from players. into numberofplayers

I think the array element referrence is there, it's just the forum code that is turning the array index into the code to switch to italic text.
 
Haven't found anything that is stomping your variable, but you do have a problem in this for loop:
for(int i=1;i<=numberofplayers;i++)
{
if ((players.gethandvalue()>winner.gethandvalue()) &&(players.gethandvalue()<=21))winner = players;
{
winnerid=i;
}

}

Your if test will assign winner if true, but then every time through the loop you are setting winnerid to i, so at the end of the loop winnerid will always be equal to numberofplayers.
 
Originally posted by: Cerebus451
Originally posted by: EagleKeeper
I took a scan through it.

What bothers me is that he is referencing players (which is an array of classes) without defining the index.

Therefore who knows what type of indexing/corruption may be occuring.

example:


player players[7];

for (int i=1 ; i <= numberofplayers ; i++)
{
if (!players.playing) continue;
}

How does the code know which players object is being referenced?

Also, the next memory variable slot after players is numberofplayers.
It may be possible that the lack of proper indexing is causing memory overflow from players. into numberofplayers

I think the array element referrence is there, it's just the forum code that is turning the array index into the code to switch to italic text.

If that is the case, the OP should use the attach code feature so we can assist.

 
If you can run it on a linux box, valgrind ("valgrind yourProgramBinary") will tell you if you're clobbering it with a bad memory access. I'd do it, but your code is unusable as currently posted.
 
Seriously.. use the attach code function!!! It saddens me to see less than half of the programming question threads not utilize it...!


Ctho: So does valgrind test for memory leaks?
 
Originally posted by: duragezic
Seriously.. use the attach code function!!! It saddens me to see less than half of the programming question threads not utilize it...!


Ctho: So does valgrind test for memory leaks?

Yep - valgrind is a very nice tool for all sorts of memory problems.
 
Originally posted by: dighn
Originally posted by: MrChad
You never initialize your player array.

player players[7];

// Need this
for (int i = 0; i < 7; i++){
players[ i] = new player();
}

players[0].SetName("Dealer");
players[1].SetName("Player 1");
players[2].SetName("Player 2");
players[3].SetName("Player 3");
players[4].SetName("Player 4");
players[5].SetName("Player 5");
players[6].SetName("Player 6");

this is C++, objects are not references by default

😱

Sorry, must have had a brain fart there.
 
Back
Top