CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 9 of 9
  1. #1
    Join Date
    Feb 2014
    Posts
    4

    Not sure why values are changing when I'm passing arrays and array sizes

    Hi, I'm working on a homework assignment that asks me to roll two die a user given number of times, find the roll sums, and a few other things. I'm working on it one module at a time and I'm running into two big problems so far.

    The first problem is that my int variable rolls changes to a number within the random number generator range of numbers after I run rolldie. I got around this by making a const equal to the user entered value of rolls just so that I could continue developing the program.

    My second problem is that the values of the arrays resultsOne[] and resultsTwo[] are changed after running findsum(). I have no idea why this is happening and I even tried passing them as const, but that changed nothing. If anyone could point me in the right direction, I will be forever grateful!

    We just started learning about passing arrays to functions, so there might be something big that I'm missing.

    Thanks!

    Code:
    #include <iostream>
    #include <cstdlib>
    
    using namespace std;
    
    void rolldie(int resultsOne[], int sizeOfresultsOne, int resultsTwo[], int sizeOfresultsTwo);
    void findsum(int resultsOne[], int sizeOfresultsOne, int resultsTwo[], int sizeOfresultsTwo, int tossSums[], int sizeOftossSums);
    
    int main()
    {
        srand(time(NULL));
        int rolls = 0;
        int resultsOne[] = {};
        int resultsTwo[] = {};
        int tossSums[] = {};
        
        cout << "Enter number of tosses : ";
        cin >> rolls;
        const int roll = rolls;
        
        rolldie(resultsOne, rolls, resultsTwo, roll);
        cout << resultsOne[0] << endl;
        cout << resultsTwo[0] << endl << endl;    
    
        
        
        findsum(resultsOne, roll, resultsTwo, roll, tossSums, roll);
    
        cout << resultsOne[0] << endl;
        cout << resultsTwo[0];
    
                
        cin.sync();cin.ignore();
        return 0;
    }
    
    void rolldie(int resultsOne[], int sizeOfresultsOne, int resultsTwo[], int sizeOfresultsTwo)
    {
       
         for(int i = 0; i < sizeOfresultsOne; i++)
         {
                 resultsOne[i] = 1 + (rand() % 6);
                 resultsTwo[i] = 1 + (rand() % 6);
         }
    
         for(int i = 0; i < sizeOfresultsTwo; i++)
         {
                 resultsTwo[i] = 1 + (rand() % 6);
         }
    }
    
    void findsum(int resultsOne[], int sizeOfresultsOne, int resultsTwo[], int sizeOfresultsTwo, int tossSums[], int sizeOftossSums)
    {
         cout << sizeOfresultsOne;
         
         for (int i = 0; i < sizeOfresultsOne; i++)
         {
             tossSums[i] = resultsOne[i] + resultsTwo[i];
         }
         
    }

  2. #2
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,822

    Re: Not sure why values are changing when I'm passing arrays and array sizes

    Code:
    int resultsOne[] = {};
    int resultsTwo[] = {};
    You haven't provided the size of the array. For arrays, the number of elements needs to be given at compile time. If the size of the arrays (or a maximum size) is not known at compile time, then you need to use dynamic arrays which you probably haven't covered yet on the course. So you need to define a const int that specifies the maximum number of rolls allowed and then define the arrays. Something like this

    Code:
    const int MaxRolls = 10;
    int resultsOne[MaxRolls] = {0);
    ...
    As it is at present, the array is defined with 0 elements so when you access/change any element yoi are using memory that has been assigned for a different usage and your program has what is called 'buffer overflow' where writing to the array overwrites something else in memory with unpredictable results! c++ doesn't do array bounds checking.

    When you obtain the number of tosses you then need to check the range to make sure its greater than 0 and less than or equal to the maximum number of rolls.
    Last edited by 2kaud; February 28th, 2014 at 04:51 PM.
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++23 Compiler: Microsoft VS2022 (17.6.5)

  3. #3
    Join Date
    Feb 2014
    Posts
    4

    Re: Not sure why values are changing when I'm passing arrays and array sizes

    Fantastic!

    I knew that I was doing something wrong. Thanks so much!

  4. #4
    Join Date
    Feb 2014
    Posts
    4

    Re: Not sure why values are changing when I'm passing arrays and array sizes

    So, I just got done with my finished program. Thanks again for the help!
    Code:
    #include <iostream>
    #include <cstdlib>
    
    using namespace std;
    
    //Declare prototypes//
    void rolldie(int resultsOne[], int sizeOfresultsOne, int resultsTwo[], int sizeOfresultsTwo);
    void findsum(int resultsOne[], int sizeOfresultsOne, int resultsTwo[], int sizeOfresultsTwo, int tossSums[], int sizeOftossSums);
    void tosscount(int numTosses, int tossSums[], int sizeOftossSums, int counter[], int sizeOfcounter);
    void display(int counter[], int sizeOfcounter, int rolls);
    
    
    int main()
    {
        
        srand(time(NULL)); //Set seed for rand()
        const int max = 100000; //Declare maximum size of arrays
        int rolls = 0; //This variable holds # of rolls entered by user
        int resultsOne[max] = {0}; //This array holds roll results for die one
        int resultsTwo[max] = {0}; //This array holds roll results for die two
        int tossSums[max] = {0}; //This array holds the sums for each dice roll
        
        /*
         -This array holds the number of times an amount from 2-12 appears in 
          the array tossSums[]
        */
        int counter[13] = {0};
        char decision = 'y'; //This variable controls the do-while loop
    
        /* 
        -This do-while loop prompts the user for a number of tosses.
        -Then, it stores the number into variable rolls.
        -Two arrays, resultsOne[] and resultsTwo[], and the # of rolls are passed to
         rolldie().
        -Three arrays, resultsOne[], resultsTwo[], and tossSums[], as well as 
         the # of rolls are passed to findsum().
        -Two arrays, tossSums[] and counter[], as well as the # of rolls 
         and the range of possible roll sums (2-12) are passed to tosscount().  
        -The array counter[], the range of possible roll sums (2-12) and
         the # of rolls are passed to display().
        */
        do
        {
            cout << "Enter number of tosses : ";
            cin >> rolls;
            rolldie(resultsOne, rolls, resultsTwo, rolls);
            findsum(resultsOne, rolls, resultsTwo, rolls, tossSums, rolls);
            tosscount(rolls, tossSums, rolls, counter, 13);
            display(counter, 13, rolls);
            cout << "Do another simulation? (y or n): ";
            cin >> decision;
        }
        while (decision == 'y' || decision == 'Y');
        
        cin.sync();cin.ignore();
        return 0;
    }
    
    
    void rolldie(int resultsOne[], int sizeOfresultsOne, int resultsTwo[], int sizeOfresultsTwo)
    {
         /*
         -These two for loops go through every element of arrays resultsOne[] and
          resultsTwo[] and assigns to each element a random number in the range 1-6
         */
         for(int i = 0; i < sizeOfresultsOne; i++)
         {
                 resultsOne[i] = 1 + (rand() % 6);
                 resultsTwo[i] = 1 + (rand() % 6);
         }
    
         for(int i = 0; i < sizeOfresultsTwo; i++)
         {
                 resultsTwo[i] = 1 + (rand() % 6);
         }
    }
    
    void findsum(int resultsOne[], int sizeOfresultsOne, int resultsTwo[], int sizeOfresultsTwo, int tossSums[], int sizeOftossSums)
    {
         /*
         -This for loop takes each element of resultsOne[] and resultsTwo[] and adds
          the sum of these elements to the same index index in the array tossSums[]
         */
         for (int i = 0; i < sizeOfresultsOne; i++)
         {
             tossSums[i] = resultsOne[i] + resultsTwo[i];
         }
         
    }
    
    void tosscount(int numTosses, int tossSums[], int sizeOftossSums, int counter[], int sizeOfcounter)
    {
         /*
         -The first for loop goes through each element of array counter[] and
          executes the nested for loop. 
         -The nested for loop goes through each element of numTosses[] and compares
          the value to the current index of the outer for loop. If the two are equal,
          the current element of counter[] is incremented by 1.
         */
         for (int i = 2; i < 13; i++)
         {
             for(int n = 0; n < numTosses; n++)
             {
                     if(tossSums[n] == i)
                     {
                          counter[i]++;
                     }
             }
         }
    }     
    
    void display(int counter[], int sizeOfcounter, int rolls)
    {
         /*
         -Variable percentage of type double is declared.
         -The # of tosses is displayed.
         -Formatted output header is displayed.
         -The for loop goes through each element of array counter[], finds the
          probability of that roll sum occuring, and displays the roll sum, the 
          number of times that sum was rolled, and the respected probability of 
          that particular sum occuring.
         */
         
         double percentage;
         cout << "Total number of tosses = " << rolls << endl;
         cout << "\tToss\t Count\t Probability" << endl;
         for (int i = 2; i < 13; i++)
         {
             percentage = ((double)counter[i]/(double)rolls) * 100;
             cout << "\t" << i << "\t" << counter[i] << "\t" << percentage << "%" << endl;
         }
    }

  5. #5
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,822

    Re: Not sure why values are changing when I'm passing arrays and array sizes

    Isn't your max (100000) a little on the high side? I would suggest a lower value (say 100) and then check that the number of tosses entered is less than this value. Even if you don't reduce this value, you should still chck the value of tosses entered. This is good program design.

    Also in tosscount() you pass sizeOfcounter as an argument but don't use it and hard code 13! The same in display. This is not good design practice.
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++23 Compiler: Microsoft VS2022 (17.6.5)

  6. #6
    Join Date
    Feb 2014
    Posts
    4

    Re: Not sure why values are changing when I'm passing arrays and array sizes

    Quote Originally Posted by 2kaud View Post
    Isn't your max (100000) a little on the high side? I would suggest a lower value (say 100) and then check that the number of tosses entered is less than this value. Even if you don't reduce this value, you should still chck the value of tosses entered. This is good program design.

    Also in tosscount() you pass sizeOfcounter as an argument but don't use it and hard code 13! The same in display. This is not good design practice.
    The max of (100000) was defined in the assignment guidelines, so I have to stick with that.

    As far as sizeOfCounter goes, my instructor told us that when passing an array to a function, you must pass the array and a variable that holds the size of the array as well. I will change the hard coded 13 to a const int variable.

    Thanks!

  7. #7
    Join Date
    Dec 2013
    Posts
    75

    Re: Not sure why values are changing when I'm passing arrays and array sizes

    Actually, for iterating through an array, you don't need to pass a variable for the size; just write:
    Code:
    for (auto& val: arrayname)
    //do useful stuff

  8. #8
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,822

    Re: Not sure why values are changing when I'm passing arrays and array sizes

    Quote Originally Posted by TSLexi View Post
    Actually, for iterating through an array, you don't need to pass a variable for the size; just write:
    Code:
    for (auto& val: arrayname)
    //do useful stuff
    in a function where the array is passed as a parameter? If this is supposed to be in c++11 then it doesn't work with VS2013. It works in the same block as the array definiton but used in a function with an array as an argument VS2013 gives error C3312.
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++23 Compiler: Microsoft VS2022 (17.6.5)

  9. #9
    Join Date
    Oct 2008
    Posts
    1,456

    Re: Not sure why values are changing when I'm passing arrays and array sizes

    function parameters declared as arrays are always parsed as pointers in c++ ( no conversion or pointer decay, you just cannot declare an array as function parameter ), so

    void f(int[3]);
    void f(int[2]);
    void f(int[]);
    void f(int*);

    all declare exactly the same function. Hence, using a range for loop ( that is defined to invoke ADL activated and std begin/end functions ) with such a parameter is like using a for loop with a pointer, giving an error as expected.

    In order to pass an array, one should either wrap it inside a struct ( or an std::array or the like ) to pass by value, or pass it by reference:

    void f(int (&param)[3]){ /*now you can*/ for( auto& i: param ) ... // param has type reference-to-array-of-three-ints

    or simply pass a pointer and a size ( as suggested by the instructor ) or a pair of pointers ...

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured