Problem with release build of program using pointers

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Cam

    Problem with release build of program using pointers

    Hi all,

    The code below is a practical exercise and works well running in the debug
    environment but fails when being compiled for a release build. I believe
    this is because the debug environment takes care of memory allocation and
    the release build relies on code to do this. My research in my books and on
    the web has not provided any great help.

    I would be grateful for advice on what I need to do to correctly allocate
    the memory resources for the code to compile correctly to release as an .exe
    program.

    Cheers,

    Cam

    Code follows:

    #include <iostream>
    #include <conio.h>

    using namespace std;

    KeyboardInput(i nt *pkey); // Gathers input
    Add1Comp(int *presult); // Carries out addition

    int key1[8], carrykey1[8], key2[8], carrykey2[8], result[8];

    int main (int *pkey) ////////////////////////////////////////////// main()
    ///////////////////////////////////////////////////////////
    {
    do
    {
    KeyboardInput(k ey1); // Calls KeyboardInput whose ouput is key1
    KeyboardInput(k ey2); // Calls KeyboardInput whose output is key2
    Add1Comp(result ); // Calls Add1Comp whose output is result
    }
    while(1);
    return 0;
    }

    int KeyboardInput (int *pkey) //////////////////////////// KeyboardInput()
    /////////////////////////////////////////////
    {
    restart:
    int counter = 0;
    cout << "\nEnter an 8 bit binary number: ";
    for (counter = 8; counter > 0; counter --)
    {
    pkey[counter] = (getche() - 48);
    }
    cout << "\n";
    for (counter = 8; counter > 0; counter --)
    {
    if (pkey[counter] != 0 && pkey[counter] != 1)
    {
    cout << "\n\nYou have entered non-binary character. Please
    restart\n\n";
    goto restart;
    }
    }
    return 0;
    }

    int Add1Comp (int *presult) /////////////////////////// Add1Comp()
    /////////////////////////////////////////////////
    {
    int latch = 0;
    restart:
    int counter, carry = 0;
    for (counter = 1; counter < 9; counter ++)
    {
    switch (key1[counter] + key2[counter] + carry)
    {
    case 0: // 0+0+0 = 0 carry 0
    presult[counter] = 0;
    cout << "\nBit " << counter << ": " << key1[counter] << " + " <<
    key2[counter] << " + " << carry << " = " << presult[counter] << " carry ";
    carry = 0;
    cout << carry;
    break;
    case 1: // 0+0+1 xor 0+1+0 xor 1+0+0 = 1 carry 0
    presult[counter] = 1;
    cout << "\nBit " << counter << ": " << key1[counter] << " + " <<
    key2[counter] << " + " << carry << " = " << presult[counter] << " carry ";
    carry = 0;
    cout << carry;
    break;
    case 2: // 1+1+0 xor 1+0+1 xor 0+1+1 = 0 carry 1
    presult[counter] = 0;
    cout << "\nBit " << counter << ": " << key1[counter] << " + " <<
    key2[counter] << " + " << carry << " = " << presult[counter] << " carry ";
    carry = 1;
    cout << carry;
    break;
    case 3: // 1+1+1 = 1 carry 1
    presult[counter] = 1;
    cout << "\nBit " << counter << ": " << key1[counter] << " + " <<
    key2[counter] << " + " << carry << " = " << presult[counter] << " carry ";
    carry = 1;
    cout << carry;
    break;
    }
    if (counter == 8 && carry == 1)
    goto addcarry;
    if (counter == 8 && latch == 1 && carry == 1)
    goto overflow;
    }
    cout << "\n\nResult of ";
    for (counter = 8; counter > 0; counter --)
    {
    if (latch)
    key1[counter] = carrykey1[counter];
    cout << key1[counter];
    }
    cout << " + ";
    for (counter = 8; counter > 0; counter --)
    {
    if (latch)
    key2[counter] = carrykey2[counter];
    cout << key2[counter];
    }
    cout << " = ";
    for (counter = 8; counter > 0; counter --)
    {
    cout << presult[counter];
    }
    cout << "\n\n-----------------------------------------\n";
    latch = 0;
    return 0;

    addcarry:
    latch = 1;
    cout << "\n\nAdd final carry:\n";
    for (counter = 1; counter < 9; counter ++)
    {
    carrykey1[counter] = key1[counter];
    key1[counter] = result[counter];
    carrykey2[counter] = key2[counter];
    key2[counter] = 0;
    presult[counter] = 0;
    }
    key2[1] = 1;
    goto restart;
    overflow:
    cout << "\nThe addition has resulted in an overflow";
    main(key1);
    }


  • Mike Wahler

    #2
    Re: Problem with release build of program using pointers


    "Cam" <retsigerymmuda thotmaildotcom> wrote in message
    news:407607cf@d uster.adelaide. on.net...[color=blue]
    > Hi all,
    >
    > The code below is a practical exercise and works well running in the debug
    > environment but fails when being compiled for a release build. I believe
    > this is because the debug environment takes care of memory allocation and
    > the release build relies on code to do this. My research in my books and[/color]
    on[color=blue]
    > the web has not provided any great help.[/color]

    Your code doesn't do any allocations.
    But it does produce undefined behavior.
    See below.
    [color=blue]
    >
    > I would be grateful for advice on what I need to do to correctly allocate
    > the memory resources for the code to compile correctly to release as an[/color]
    ..exe[color=blue]
    > program.
    >
    > Cheers,
    >
    > Cam
    >
    > Code follows:
    >
    > #include <iostream>
    > #include <conio.h>[/color]

    This is a nonstandard header. Please omit such
    from code posted here.
    [color=blue]
    > using namespace std;
    >
    > KeyboardInput(i nt *pkey); // Gathers input
    > Add1Comp(int *presult); // Carries out addition
    >
    > int key1[8], carrykey1[8], key2[8], carrykey2[8], result[8];[/color]

    Each of these arrays has eight elements. Therefore the
    valid range of subscripts for each is from zero through seven.
    [color=blue]
    >
    > int main (int *pkey) ////////////////////////////////////////////// main()[/color]

    If you use them, main()'s first two arguments must
    be type 'int', and 'char **', respectively.
    [color=blue]
    > ///////////////////////////////////////////////////////////
    > {
    > do
    > {
    > KeyboardInput(k ey1); // Calls KeyboardInput whose ouput is key1
    > KeyboardInput(k ey2); // Calls KeyboardInput whose output is key2
    > Add1Comp(result ); // Calls Add1Comp whose output is result
    > }
    > while(1);
    > return 0;
    > }
    >
    > int KeyboardInput (int *pkey) //////////////////////////// KeyboardInput()
    > /////////////////////////////////////////////
    > {
    > restart:
    > int counter = 0;
    > cout << "\nEnter an 8 bit binary number: ";
    > for (counter = 8; counter > 0; counter --)[/color]

    'counter' starts out with a value of 8.
    [color=blue]
    > {
    > pkey[counter] = (getche() - 48);[/color]

    Element eight is out of bound for your arrays 'key1' and
    'key2' above, whose addresses you've passed to this function.
    This gives 'undefined behavior'.

    Also not that 'getche()' is a nonstandard function.
    Please omit such from code posted here.
    [color=blue]
    > }
    > cout << "\n";
    > for (counter = 8; counter > 0; counter --)
    > {
    > if (pkey[counter] != 0 && pkey[counter] != 1)[/color]

    And again.
    [color=blue]
    > {
    > cout << "\n\nYou have entered non-binary character. Please
    > restart\n\n";
    > goto restart;[/color]

    Consider using a loop instead of a 'goto'.
    [color=blue]
    > }
    > }
    > return 0;
    > }
    >
    > int Add1Comp (int *presult) /////////////////////////// Add1Comp()
    > /////////////////////////////////////////////////
    > {
    > int latch = 0;
    > restart:
    > int counter, carry = 0;
    > for (counter = 1; counter < 9; counter ++)[/color]

    You have the same problems here. Array indices are
    from zero the the number of elements less one.

    for (counter = 0; counter < 8; counter ++)

    More below.
    [color=blue]
    > {
    > switch (key1[counter] + key2[counter] + carry)
    > {
    > case 0: // 0+0+0 = 0 carry 0
    > presult[counter] = 0;
    > cout << "\nBit " << counter << ": " << key1[counter] << " + " <<
    > key2[counter] << " + " << carry << " = " << presult[counter] << " carry ";
    > carry = 0;
    > cout << carry;
    > break;
    > case 1: // 0+0+1 xor 0+1+0 xor 1+0+0 = 1 carry 0
    > presult[counter] = 1;
    > cout << "\nBit " << counter << ": " << key1[counter] << " + " <<
    > key2[counter] << " + " << carry << " = " << presult[counter] << " carry ";
    > carry = 0;
    > cout << carry;
    > break;
    > case 2: // 1+1+0 xor 1+0+1 xor 0+1+1 = 0 carry 1
    > presult[counter] = 0;
    > cout << "\nBit " << counter << ": " << key1[counter] << " + " <<
    > key2[counter] << " + " << carry << " = " << presult[counter] << " carry ";
    > carry = 1;
    > cout << carry;
    > break;
    > case 3: // 1+1+1 = 1 carry 1
    > presult[counter] = 1;
    > cout << "\nBit " << counter << ": " << key1[counter] << " + " <<
    > key2[counter] << " + " << carry << " = " << presult[counter] << " carry ";
    > carry = 1;
    > cout << carry;
    > break;
    > }
    > if (counter == 8 && carry == 1)
    > goto addcarry;
    > if (counter == 8 && latch == 1 && carry == 1)
    > goto overflow;
    > }
    > cout << "\n\nResult of ";
    > for (counter = 8; counter > 0; counter --)
    > {
    > if (latch)
    > key1[counter] = carrykey1[counter];
    > cout << key1[counter];
    > }
    > cout << " + ";
    > for (counter = 8; counter > 0; counter --)
    > {
    > if (latch)
    > key2[counter] = carrykey2[counter];
    > cout << key2[counter];
    > }
    > cout << " = ";
    > for (counter = 8; counter > 0; counter --)
    > {
    > cout << presult[counter];
    > }
    > cout << "\n\n-----------------------------------------\n";
    > latch = 0;
    > return 0;
    >
    > addcarry:
    > latch = 1;
    > cout << "\n\nAdd final carry:\n";
    > for (counter = 1; counter < 9; counter ++)
    > {
    > carrykey1[counter] = key1[counter];
    > key1[counter] = result[counter];
    > carrykey2[counter] = key2[counter];
    > key2[counter] = 0;
    > presult[counter] = 0;
    > }
    > key2[1] = 1;
    > goto restart;
    > overflow:
    > cout << "\nThe addition has resulted in an overflow";
    > main(key1);[/color]

    'main()' may not be called recursively in C++.
    [color=blue]
    > }[/color]

    You're probably correct that your implementation' s 'debug
    mode' was 'protecting' you from a crash.

    -Mike


    Comment

    • Mike Wahler

      #3
      Re: Problem with release build of program using pointers


      "Cam" <retsigerymmuda thotmaildotcom> wrote in message
      news:407607cf@d uster.adelaide. on.net...[color=blue]
      > Hi all,
      >
      > The code below is a practical exercise and works well running in the debug
      > environment but fails when being compiled for a release build. I believe
      > this is because the debug environment takes care of memory allocation and
      > the release build relies on code to do this. My research in my books and[/color]
      on[color=blue]
      > the web has not provided any great help.[/color]

      Your code doesn't do any allocations.
      But it does produce undefined behavior.
      See below.
      [color=blue]
      >
      > I would be grateful for advice on what I need to do to correctly allocate
      > the memory resources for the code to compile correctly to release as an[/color]
      ..exe[color=blue]
      > program.
      >
      > Cheers,
      >
      > Cam
      >
      > Code follows:
      >
      > #include <iostream>
      > #include <conio.h>[/color]

      This is a nonstandard header. Please omit such
      from code posted here.
      [color=blue]
      > using namespace std;
      >
      > KeyboardInput(i nt *pkey); // Gathers input
      > Add1Comp(int *presult); // Carries out addition
      >
      > int key1[8], carrykey1[8], key2[8], carrykey2[8], result[8];[/color]

      Each of these arrays has eight elements. Therefore the
      valid range of subscripts for each is from zero through seven.
      [color=blue]
      >
      > int main (int *pkey) ////////////////////////////////////////////// main()[/color]

      If you use them, main()'s first two arguments must
      be type 'int', and 'char **', respectively.
      [color=blue]
      > ///////////////////////////////////////////////////////////
      > {
      > do
      > {
      > KeyboardInput(k ey1); // Calls KeyboardInput whose ouput is key1
      > KeyboardInput(k ey2); // Calls KeyboardInput whose output is key2
      > Add1Comp(result ); // Calls Add1Comp whose output is result
      > }
      > while(1);
      > return 0;
      > }
      >
      > int KeyboardInput (int *pkey) //////////////////////////// KeyboardInput()
      > /////////////////////////////////////////////
      > {
      > restart:
      > int counter = 0;
      > cout << "\nEnter an 8 bit binary number: ";
      > for (counter = 8; counter > 0; counter --)[/color]

      'counter' starts out with a value of 8.
      [color=blue]
      > {
      > pkey[counter] = (getche() - 48);[/color]

      Element eight is out of bound for your arrays 'key1' and
      'key2' above, whose addresses you've passed to this function.
      This gives 'undefined behavior'.

      Also not that 'getche()' is a nonstandard function.
      Please omit such from code posted here.
      [color=blue]
      > }
      > cout << "\n";
      > for (counter = 8; counter > 0; counter --)
      > {
      > if (pkey[counter] != 0 && pkey[counter] != 1)[/color]

      And again.
      [color=blue]
      > {
      > cout << "\n\nYou have entered non-binary character. Please
      > restart\n\n";
      > goto restart;[/color]

      Consider using a loop instead of a 'goto'.
      [color=blue]
      > }
      > }
      > return 0;
      > }
      >
      > int Add1Comp (int *presult) /////////////////////////// Add1Comp()
      > /////////////////////////////////////////////////
      > {
      > int latch = 0;
      > restart:
      > int counter, carry = 0;
      > for (counter = 1; counter < 9; counter ++)[/color]

      You have the same problems here. Array indices are
      from zero the the number of elements less one.

      for (counter = 0; counter < 8; counter ++)

      More below.
      [color=blue]
      > {
      > switch (key1[counter] + key2[counter] + carry)
      > {
      > case 0: // 0+0+0 = 0 carry 0
      > presult[counter] = 0;
      > cout << "\nBit " << counter << ": " << key1[counter] << " + " <<
      > key2[counter] << " + " << carry << " = " << presult[counter] << " carry ";
      > carry = 0;
      > cout << carry;
      > break;
      > case 1: // 0+0+1 xor 0+1+0 xor 1+0+0 = 1 carry 0
      > presult[counter] = 1;
      > cout << "\nBit " << counter << ": " << key1[counter] << " + " <<
      > key2[counter] << " + " << carry << " = " << presult[counter] << " carry ";
      > carry = 0;
      > cout << carry;
      > break;
      > case 2: // 1+1+0 xor 1+0+1 xor 0+1+1 = 0 carry 1
      > presult[counter] = 0;
      > cout << "\nBit " << counter << ": " << key1[counter] << " + " <<
      > key2[counter] << " + " << carry << " = " << presult[counter] << " carry ";
      > carry = 1;
      > cout << carry;
      > break;
      > case 3: // 1+1+1 = 1 carry 1
      > presult[counter] = 1;
      > cout << "\nBit " << counter << ": " << key1[counter] << " + " <<
      > key2[counter] << " + " << carry << " = " << presult[counter] << " carry ";
      > carry = 1;
      > cout << carry;
      > break;
      > }
      > if (counter == 8 && carry == 1)
      > goto addcarry;
      > if (counter == 8 && latch == 1 && carry == 1)
      > goto overflow;
      > }
      > cout << "\n\nResult of ";
      > for (counter = 8; counter > 0; counter --)
      > {
      > if (latch)
      > key1[counter] = carrykey1[counter];
      > cout << key1[counter];
      > }
      > cout << " + ";
      > for (counter = 8; counter > 0; counter --)
      > {
      > if (latch)
      > key2[counter] = carrykey2[counter];
      > cout << key2[counter];
      > }
      > cout << " = ";
      > for (counter = 8; counter > 0; counter --)
      > {
      > cout << presult[counter];
      > }
      > cout << "\n\n-----------------------------------------\n";
      > latch = 0;
      > return 0;
      >
      > addcarry:
      > latch = 1;
      > cout << "\n\nAdd final carry:\n";
      > for (counter = 1; counter < 9; counter ++)
      > {
      > carrykey1[counter] = key1[counter];
      > key1[counter] = result[counter];
      > carrykey2[counter] = key2[counter];
      > key2[counter] = 0;
      > presult[counter] = 0;
      > }
      > key2[1] = 1;
      > goto restart;
      > overflow:
      > cout << "\nThe addition has resulted in an overflow";
      > main(key1);[/color]

      'main()' may not be called recursively in C++.
      [color=blue]
      > }[/color]

      You're probably correct that your implementation' s 'debug
      mode' was 'protecting' you from a crash.

      -Mike


      Comment

      • Victor Bazarov

        #4
        Re: Problem with release build of program using pointers

        "Cam" <retsigerymmuda thotmaildotcom> wrote...[color=blue]
        > The code below is a practical exercise and works well [...][/color]

        Which is not surprising. Your code is full of parts that cause
        undefined behaviour. One of possible behaviours is "to work as
        expected". Another is "not to work as expected". You apparently
        witnessed both, one in debug the other in release mode. They did
        not have to be particularly that. They could have been vice versa
        or both the same. It's impossible to predict because it's simply
        _undefined_.

        As soon as you fix it to comply with C++ Standard, you might be
        surprised that it works always...

        To be specific, check out what indices you used to access your
        8-element arrays. Think of the correct range in that case and
        verify that your indices always fall in that range...

        Good luck!

        V


        Comment

        • Victor Bazarov

          #5
          Re: Problem with release build of program using pointers

          "Cam" <retsigerymmuda thotmaildotcom> wrote...[color=blue]
          > The code below is a practical exercise and works well [...][/color]

          Which is not surprising. Your code is full of parts that cause
          undefined behaviour. One of possible behaviours is "to work as
          expected". Another is "not to work as expected". You apparently
          witnessed both, one in debug the other in release mode. They did
          not have to be particularly that. They could have been vice versa
          or both the same. It's impossible to predict because it's simply
          _undefined_.

          As soon as you fix it to comply with C++ Standard, you might be
          surprised that it works always...

          To be specific, check out what indices you used to access your
          8-element arrays. Think of the correct range in that case and
          verify that your indices always fall in that range...

          Good luck!

          V


          Comment

          • John Harrison

            #6
            [OT] Re: Problem with release build of program using pointers


            "Cam" <retsigerymmuda thotmaildotcom> wrote in message
            news:407607cf@d uster.adelaide. on.net...[color=blue]
            > Hi all,
            >
            > The code below is a practical exercise and works well running in the debug
            > environment but fails when being compiled for a release build. I believe
            > this is because the debug environment takes care of memory allocation and
            > the release build relies on code to do this.[/color]

            That's untrue.

            john


            Comment

            • John Harrison

              #7
              [OT] Re: Problem with release build of program using pointers


              "Cam" <retsigerymmuda thotmaildotcom> wrote in message
              news:407607cf@d uster.adelaide. on.net...[color=blue]
              > Hi all,
              >
              > The code below is a practical exercise and works well running in the debug
              > environment but fails when being compiled for a release build. I believe
              > this is because the debug environment takes care of memory allocation and
              > the release build relies on code to do this.[/color]

              That's untrue.

              john


              Comment

              • Cam

                #8
                Re: [OT] Re: Problem with release build of program using pointers

                Hi John,

                Thank you for your help previously.

                The fact that my arrays start with an element at position 1 doesn't seem to
                cause problems in the debug environment.

                Is this is what is preventing the code from undergoing a release build?

                Thanks,

                Cam


                "John Harrison" <john_andronicu s@hotmail.com> wrote in message
                news:c55c3m$2ns 1ou$1@ID-196037.news.uni-berlin.de...
                |
                | "Cam" <retsigerymmuda thotmaildotcom> wrote in message
                | news:407607cf@d uster.adelaide. on.net...
                | > Hi all,
                | >
                | > The code below is a practical exercise and works well running in the
                debug
                | > environment but fails when being compiled for a release build. I believe
                | > this is because the debug environment takes care of memory allocation
                and
                | > the release build relies on code to do this.
                |
                | That's untrue.
                |
                | john
                |
                |


                Comment

                • Cam

                  #9
                  Re: [OT] Re: Problem with release build of program using pointers

                  Hi John,

                  Thank you for your help previously.

                  The fact that my arrays start with an element at position 1 doesn't seem to
                  cause problems in the debug environment.

                  Is this is what is preventing the code from undergoing a release build?

                  Thanks,

                  Cam


                  "John Harrison" <john_andronicu s@hotmail.com> wrote in message
                  news:c55c3m$2ns 1ou$1@ID-196037.news.uni-berlin.de...
                  |
                  | "Cam" <retsigerymmuda thotmaildotcom> wrote in message
                  | news:407607cf@d uster.adelaide. on.net...
                  | > Hi all,
                  | >
                  | > The code below is a practical exercise and works well running in the
                  debug
                  | > environment but fails when being compiled for a release build. I believe
                  | > this is because the debug environment takes care of memory allocation
                  and
                  | > the release build relies on code to do this.
                  |
                  | That's untrue.
                  |
                  | john
                  |
                  |


                  Comment

                  • John Harrison

                    #10
                    Re: [OT] Re: Problem with release build of program using pointers


                    "Cam" <retsigerymmuda thotmaildotcom> wrote in message
                    news:4077892c@d uster.adelaide. on.net...[color=blue]
                    > Hi John,
                    >
                    > Thank you for your help previously.
                    >
                    > The fact that my arrays start with an element at position 1 doesn't seem[/color]
                    to[color=blue]
                    > cause problems in the debug environment.
                    >
                    > Is this is what is preventing the code from undergoing a release build?
                    >[/color]

                    Yes, arrays start at position 0 in C++, that applies to debug builds,
                    release builds, different compilers, everything.

                    As others explained you program has undefined behaviour. And undefined
                    behaviour means anything can happen, including working in the debug build
                    and not working in the release build.

                    If you change your program so that it does not have undefined behaviour,
                    then it will work in any build.

                    john


                    Comment

                    • John Harrison

                      #11
                      Re: [OT] Re: Problem with release build of program using pointers


                      "Cam" <retsigerymmuda thotmaildotcom> wrote in message
                      news:4077892c@d uster.adelaide. on.net...[color=blue]
                      > Hi John,
                      >
                      > Thank you for your help previously.
                      >
                      > The fact that my arrays start with an element at position 1 doesn't seem[/color]
                      to[color=blue]
                      > cause problems in the debug environment.
                      >
                      > Is this is what is preventing the code from undergoing a release build?
                      >[/color]

                      Yes, arrays start at position 0 in C++, that applies to debug builds,
                      release builds, different compilers, everything.

                      As others explained you program has undefined behaviour. And undefined
                      behaviour means anything can happen, including working in the debug build
                      and not working in the release build.

                      If you change your program so that it does not have undefined behaviour,
                      then it will work in any build.

                      john


                      Comment

                      Working...