Puzzled C++ code

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • yqwen
    New Member
    • Apr 2007
    • 8

    Puzzled C++ code

    please run the following code, and kindly advise why the result is 20 instead of 10? thanks in advance
    Code:
    #include <iostream>
    #include <string>
    #include <vector>
    
    using namespace std;
    
    class A
    {
    public:
    	A() : i(1) {} 
    	int i;
    };
    
    class B : public A
    {
    public:
    	B() : j(3) {} 
    	int j; 
    };
    
    int f(A* p, int count)
    {
    	int total=0;
    
    	for(int k=0; k<count; k++)
    	{
    		int temp = p->i;
    		p++;
    		cout << " k =  " << k << ", " << temp << endl; 
    		total += temp;
    	}
    
    	return (total);
    }
    
    int main() {
    	B b[10];
    	cout << f(b,10);
    	
    	return 0;
    }
    Last edited by AdrianH; Apr 19 '07, 08:37 PM. Reason: Added code tags
  • r035198x
    MVP
    • Sep 2006
    • 13225

    #2
    Originally posted by yqwen
    please run the following code, and kindly advise why the result is 20 instead of 10? thanks in advance

    #include <iostream>
    #include <string>
    #include <vector>

    using namespace std;

    class A
    {
    public:
    A() : i(1) {}
    int i;
    };

    class B : public A
    {
    public:
    B() : j(3) {}
    int j;
    };

    int f(A* p, int count)
    {
    int total=0;

    for(int k=0; k<count; k++)
    {
    int temp = p->i;
    p++;
    cout << " k = " << k << ", " << temp << endl;
    total += temp;
    }

    return (total);
    }

    int main() {
    B b[10];
    cout << f(b,10);

    return 0;
    }
    1.) Please use code tags when posting code
    2.)Why don't you tell us why you expect 10 instead of 20 first?

    Comment

    • LaneWolf
      New Member
      • Apr 2007
      • 1

      #3
      Originally posted by yqwen
      please run the following code, and kindly advise why the result is 20 instead of 10? thanks in advance

      #include <iostream>
      #include <string>
      #include <vector>

      using namespace std;

      class A
      {
      public:
      A() : i(1) {}
      int i;
      };

      class B : public A
      {
      public:
      B() : j(3) {}
      int j;
      };

      int f(A* p, int count)
      {
      int total=0;

      for(int k=0; k<count; k++)
      {
      int temp = p->i;
      p++;
      cout << " k = " << k << ", " << temp << endl;
      total += temp;
      }

      return (total);
      }

      int main() {
      B b[10];
      cout << f(b,10);

      return 0;
      }
      Try print out sizeoff(A) and sizeof(b) to see the problem ;)

      Comment

      • yqwen
        New Member
        • Apr 2007
        • 8

        #4
        Originally posted by r035198x
        1.) Please use code tags when posting code
        2.)Why don't you tell us why you expect 10 instead of 20 first?
        1. Sorry, I am new here, didn't know the norm and everything.
        2. The reason I am expecting 10 is because I thought (still think) that for the array of b, data member i should equal 1 for every element, so the summation of such should turn out to be 10. I know something is wrong but I cannot figure out what that is.

        thank you very much.

        Comment

        • yqwen
          New Member
          • Apr 2007
          • 8

          #5
          Originally posted by LaneWolf
          Try print out sizeoff(A) and sizeof(b) to see the problem ;)
          I am sorry but are you trying to help? I hope you can understand that I am pretty puzzled by this problem.

          Comment

          • Banfa
            Recognized Expert Expert
            • Feb 2006
            • 9067

            #6
            Originally posted by yqwen
            I am sorry but are you trying to help? I hope you can understand that I am pretty puzzled by this problem.
            I can understand that because LaneWolf's clue is rather oblique however it is at the root of the problem.

            Examine these 2 lines of your code

            Code:
                p++;
                cout << " k = " << k << ", " << temp << endl;
            The first is the line that is manifesting the error (that is causing the error to be apparent, the actual error is a little more fundamental), can you explain what you thing it is doing? Do you understand how pointer arithmetic works in C++?

            The second line is outputting data that should give you a clue as to what is going wrong.

            Comment

            • yqwen
              New Member
              • Apr 2007
              • 8

              #7
              Thanks.

              1. This is a question from an online C++ aptitude test.
              2. I understand that array should not be used in a polymorphism setting.
              3. I just wanted to know why it still produces a seemingly OK result, which happens to be the correct choice in the test. (I mean no matter how absurd it is, it still follow some logic to produce 20, so I wanted to know why it's 20)


              Originally posted by Banfa
              I can understand that because LaneWolf's clue is rather oblique however it is at the root of the problem.

              Examine these 2 lines of your code

              Code:
                  p++;
                  cout << " k = " << k << ", " << temp << endl;
              The first is the line that is manifesting the error (that is causing the error to be apparent, the actual error is a little more fundamental), can you explain what you thing it is doing? Do you understand how pointer arithmetic works in C++?

              The second line is outputting data that should give you a clue as to what is going wrong.

              Comment

              • Ganon11
                Recognized Expert Specialist
                • Oct 2006
                • 3651

                #8
                Each time the statement p++ is executed, p is set to point to some spot in front of the previous spot. The difference between the old and new address is determined by the size of the object type p points to. Since the function tells us p points to an object of type A, it assumes the only data member included is i (an integer), and increments p by the proper amount (1 byte, the size of an integer).

                p really points to an object of type B, which has 2 integers; thus taking up twice the room of A. So when p is incremented 'to a new A object', it is really pointing to the B portion of that object - that is, the memory which the compiler assumes to be an A object is actually a B object. Since both classes have only one integer data member, you are able to access j as if it were an i in an A object.

                Thus, you are actually adding both i and j from the first five B objects in your array with this function.

                Some of my explanation is probably incorrect regarding the specifics of how each object is stored in memory, in which case I'm sure Banfa will be glad to help out. However, this is my analysis of the output you are getting.

                Comment

                • Banfa
                  Recognized Expert Expert
                  • Feb 2006
                  • 9067

                  #9
                  Originally posted by Ganon11
                  Some of my explanation is probably incorrect regarding the specifics of how each object is stored in memory, in which case I'm sure Banfa will be glad to help out. However, this is my analysis of the output you are getting.
                  No need, you have it pretty much spot on.

                  Comment

                  • yqwen
                    New Member
                    • Apr 2007
                    • 8

                    #10
                    Ganon11:

                    Thank you very much for the clarafiction and I admire your patience and time for putting up the words. The concept is now crystal clear to me.

                    -yqwen


                    Originally posted by Ganon11
                    Each time the statement p++ is executed, p is set to point to some spot in front of the previous spot. The difference between the old and new address is determined by the size of the object type p points to. Since the function tells us p points to an object of type A, it assumes the only data member included is i (an integer), and increments p by the proper amount (1 byte, the size of an integer).

                    p really points to an object of type B, which has 2 integers; thus taking up twice the room of A. So when p is incremented 'to a new A object', it is really pointing to the B portion of that object - that is, the memory which the compiler assumes to be an A object is actually a B object. Since both classes have only one integer data member, you are able to access j as if it were an i in an A object.

                    Thus, you are actually adding both i and j from the first five B objects in your array with this function.

                    Some of my explanation is probably incorrect regarding the specifics of how each object is stored in memory, in which case I'm sure Banfa will be glad to help out. However, this is my analysis of the output you are getting.

                    Comment

                    • Atli
                      Recognized Expert Expert
                      • Nov 2006
                      • 5062

                      #11
                      Originally posted by Ganon11
                      ... (1 byte, the size of an integer) ...
                      Hi. This is probbly a stupid question but...
                      An integer is 1 byte in C++? Dont bytes have a max value of 255?

                      Comment

                      • Banfa
                        Recognized Expert Expert
                        • Feb 2006
                        • 9067

                        #12
                        Originally posted by Atli
                        An integer is 1 byte in C++?
                        No at least 2 bytes actually I assume that's a typo on Ganons part.

                        Originally posted by Atli
                        Dont bytes have a max value of 255?
                        No it depends on how many bits are in the byte (which is not fixed by the standard).

                        Comment

                        • Atli
                          Recognized Expert Expert
                          • Nov 2006
                          • 5062

                          #13
                          Ahh ok I see, thats a stupid thing not to have a fixed standard for.

                          Comment

                          • Banfa
                            Recognized Expert Expert
                            • Feb 2006
                            • 9067

                            #14
                            Originally posted by Atli
                            Ahh ok I see, thats a stupid thing not to have a fixed standard for.
                            No it's not, if your platform is 7 bit or 9 bit having your programming language fixed to 8 bit bytes would be a stupid thing to do (oh and 7 and 9 bit platforms do exist).

                            You are falling into the trap (and TBH so do most people) of assuming that all platforms share the same characteristics as the platforms(s) you use.

                            Comment

                            • Ganon11
                              Recognized Expert Specialist
                              • Oct 2006
                              • 3651

                              #15
                              Originally posted by Banfa
                              No at least 2 bytes actually I assume that's a typo on Ganons part.
                              Yeah, dont know what I was thinking when I typed that. Thanks for the catch on that one.

                              Comment

                              Working...