434,916 Members | 1,068 Online + Ask a Question
Need help? Post your question and get tips & solutions from a community of 434,916 IT Pros & Developers. It's quick & easy.

Can someone please explain the output of this code?

 P: n/a Hi, Can some one please explain why the output of this program is 15 #include using namespace std; class A { public: A():i(1) {} int i; }; class B: public A { public: B():j(2) {} int j; }; int f(A* p, int count) { int total = 0; for(int i=0; ii; } return(total); } int main() { B b; cout << f(b,10); return 0; } Regards, Jul 27 '07 #1
3 Replies

 P: n/a Aarti wrote: Hi, Can some one please explain why the output of this program is 15 [...] class A [...] class B: public A [...] int f(A* p, int count) { int total = 0; for(int i=0; ii; } return(total); } int main() { B b; cout << f(b,10); return 0; } You invoked undefined behaviour by treating an array of Bs as array of As. See Item 3 "Never treat arrays polymorphically" in Scott Meyers's "More Effective C++" -- Thomas http://www.netmeister.org/news/learn2quote.html Jul 27 '07 #2

 P: n/a Aarti using namespace std; class A { public: A():i(1) {} int i; }; class B: public A { public: B():j(2) {} int j; }; Note, sizeof(B) sizeof(A). For the sake of this explanation, let's assume that sizeof(B) is 8 and sizeof(A) is 4. int f(A* p, int count) { int total = 0; for(int i=0; ii; The increment above moves 'p' by sizeof(A) bytes. i.e., 4 bytes, but since the object pointed to by 'p' is really a B, 'p' now points to the middle of a B object. } return(total); } int main() { B b; In the above line, you create an array of B. If sizeof(B) is 8, and b is at address location 0x0, then b is at address location 0x8. cout << f(b,10); return 0; } Regards, Jul 27 '07 #3

 P: n/a You have exercised a big no-no. When you increment a pointer, what you are effectively doing is adding the sizeof the pointee type to the value of the pointer. This allows you to visit the next element of an array automatically. What you have done here is passed an array of B- s (which are larger than A-s) into your function and trying to access it as though it were A-s. So, what happens is that you take your pointer and add sizeof A to it. This means that your pointer now points into the middle of your B object somewhere. It just so happens that since this class is simple and nothing faults, but you are now treating the middle of the B as another A. This is bad. It turns out that in your example you effectivly access b.i + b.j + b.i + b.j .... and so forth. This gives 5 * 1 + 5 * 2 = 15. Normally, I might expect a fault if things were more complicated than simple ints and it is definitely undefined behavior. joe Jul 27 '07 #4

This discussion thread is closed

Replies have been disabled for this discussion. 