By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
432,002 Members | 2,137 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 432,002 IT Pros & Developers. It's quick & easy.

Can some one please explain this code

P: n/a
# include <iostream>

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; i < count ; ++i )
{ total += p->i; }

return (total);
}

int main()
{
std::cout << f(b,10) <<std::endl;
std::cin.get() ;
return 0 ;
}
The output of the above code is 15. But, i expected 10?

Thanks in advance to all..

Nov 14 '07 #1
Share this Question
Share on Google+
12 Replies


P: n/a
raghukumar wrote:
# include <iostream>

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; i < count ; ++i )
{ total += p->i; }

return (total);
}

int main()
{
std::cout << f(b,10) <<std::endl;
std::cin.get() ;
return 0 ;
}
The output of the above code is 15.
Nope, the code does not compile because:

std::cout << f(b,10) <<std::endl;
^

The identifier b has no meaning.

But, i expected 10?
The obvious guess would be that the part of the code that you did not show
has undefined behavior.
Best

Kai-Uwe Bux
Nov 14 '07 #2

P: n/a
On Nov 14, 9:53 am, raghukumar <raghukumar.r...@gmail.comwrote:
# include <iostream>

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; i < count ; ++i )
{ total += p->i; }

return (total);

}

int main()
{
std::cout << f(b,10) <<std::endl;
std::cin.get() ;
return 0 ;

}

The output of the above code is 15. But, i expected 10?

Thanks in advance to all..
sorry friends..
# include <iostream>

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; i < count ; ++i )
{ total += p++->i; }

return (total);

}

int main()
{
B b[10] ;
std::cout << f(b,10) <<std::endl;
std::cin.get() ;
return 0 ;

}
The above is the full code.

thanks ,

Nov 14 '07 #3

P: n/a
raghukumar wrote:
>
int f(A* p, int count)
{
int total = 0 ;
for (int i=0; i < count ; ++i )
{ total += p++->i; }
p is a pointer to A, p++ increments p by sizeof(A).
return (total);

}

int main()
{
B b[10] ;
std::cout << f(b,10) <<std::endl;
You are passing an array of 10 Bs, a B is bigger than an A.

--
Ian Collins.
Nov 14 '07 #4

P: n/a
You are passing an array of 10 Bs, a B is bigger than an A.
Hey i din't get this part, B is bigger than A agreed, but i am saying

total += p++->i

where i is member variable of A, initialized to 1.

Nov 14 '07 #5

P: n/a
raghukumar <ra*************@gmail.comwrote in
news:11**********************@v23g2000prn.googlegr oups.com:
>
>You are passing an array of 10 Bs, a B is bigger than an A.

Hey i din't get this part, B is bigger than A agreed, but i am saying

total += p++->i

where i is member variable of A, initialized to 1.

When you increment a pointer, it behaves very much like it was
performing
(T *)((char *)p + sizeof(T)). The problem you have is that when you
increment an A* it will add sizeof(A) to the pointer. Your array is of
B's which have a different size than A. So to give a short example of
what is happening. You have:

0: 1
1: 2
2: 1
3: 2

and so on in memory. In this example, the size of A is 1 and the sizeof
B is 2. Your function has no idea that Bs even exist (you pass it an
A*) so as far it it's concerned you have an array of A's. The pointer
will therefore visit the addresses 0, 0 + sizeof(A) = 1, 1 + sizeof(A) =
2, 2 + sizeof(A) = 3 ... This is undefined behavior, but most compilers
won't detect it as such and will happily give you whatever happens to be
in the memory locations visited. In this case, you get 1, 2, 1, 2 ....
And that results 5 1s and 5 2s giving 15. It is only because you only
have the 2 integers in your classes that this isn't just a totally wacky
value. Of course, your machine architecture with have different values
for the sizeof an in and the addresses they exist in, but the behavior
is the same.

HTH
joe
Nov 14 '07 #6

P: n/a
Hi,
Your function has no idea that Bs even exist (you pass it an
A*) so as far it it's concerned you have an array of A's. The pointer
will therefore visit the addresses 0, 0 + sizeof(A) = 1, 1 + sizeof(A) =
2, 2 + sizeof(A) = 3 ... This is undefined behavior, but most compilers
won't detect it as such and will happily give you whatever happens to be
in the memory locations visited. In this case, you get 1, 2, 1, 2 ....
And that results 5 1s and 5 2s giving 15. It is only because you only
have the 2 integers in your classes that this isn't just a totally wacky
value. Of course, your machine architecture with have different values
for the sizeof an in and the addresses they exist in, but the behavior
is the same.
I was thinking on the same line as mentioned above, and this is what i
realized. Just for testing,
i changed j variable's initial value to 3 in class B. Then ran the
program, as you mentioned instead of getting 1,1,1,1 or 1,2,1,2, it
gave 1,3,1,3(sum=20). This indicates to me that the value which i am
getting as an output, which is 20, is completely depend on how the
internal class structure is stored in memory. But, i don't know what
does standard say anything about this. So, this means can i assume
this behavior is not undefined, as any one at given point in time can
detect the value of the output. If it's really has undefined
behavior, can somebody please show me the right direction, so that i
can get some proof(code), which makes me believe.

Thanks for all your guidance,
Nov 14 '07 #7

P: n/a
On Nov 14, 6:03 pm, raghukumar <raghukumar.r...@gmail.comwrote:
If it's really has undefined
behavior, can somebody please show me the right direction, so that i
can get some proof(code), which makes me believe.

Thanks for all your guidance,
If you want to use pointer arithmetic, you are bounded
to the actual (base) type. Therefore if you define
an array of B's, the next item is not at (A+1), but
at (B+1). Therefore (A+1) would send you to who knows
where. To prove this, simply change the array to
an array of real A's, otherwise don't use pointer
arithmetic for the traversal (dangerous!).

Code below would give you the correct result.

#include <iostream>

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; i < count ; ++i )
{
total += p++->i;
}
return (total);
}

int main()
{
A a[10];
std::cout << f(a,10) << std::endl;
std::cin.get() ;
return 0 ;
}

Nov 14 '07 #8

P: n/a
raghukumar <ra*************@gmail.comwrote in news:1195059799.037952.79770
@t8g2000prg.googlegroups.com:
>
I was thinking on the same line as mentioned above, and this is what i
realized. Just for testing,
i changed j variable's initial value to 3 in class B. Then ran the
program, as you mentioned instead of getting 1,1,1,1 or 1,2,1,2, it
gave 1,3,1,3(sum=20). This indicates to me that the value which i am
getting as an output, which is 20, is completely depend on how the
internal class structure is stored in memory. But, i don't know what
does standard say anything about this. So, this means can i assume
this behavior is not undefined, as any one at given point in time can
detect the value of the output. If it's really has undefined
behavior, can somebody please show me the right direction, so that i
can get some proof(code), which makes me believe.
The standard says this is undefined behavior. The object layout is compiler
dependent and there is no guarantees about much of anything. It just happens
give something sensible in your case.

Well, if you want proof that what you are doing is a bad idea, change your j
variable to a double with the value of 30000 and then see what you get.

What you need to do is iterate through B's and that will give you the right answer.
QED.

joe
Nov 14 '07 #9

P: n/a
On Wed, 14 Nov 2007 11:36:04 +0000, raghukumar wrote:
>You are passing an array of 10 Bs, a B is bigger than an A.

Hey i din't get this part, B is bigger than A agreed, but i am saying

total += p++->i

where i is member variable of A, initialized to 1.
Effect of expression p++, where p is of type A * may be:
1) If p points to an element of array of type A - p will point to next
element of this array (or past the end if before p pointed to the last
element)
2) In any other case it has undefined behaviour.

In your code p doesn't point to an array of A (it's an array of B), so
you have undefined behaviour.

--
Tadeusz B. Kopec (tk****@NOSPAMPLEASElife.pl)
Blinding speed can compensate for a lot of deficiencies.
-- David Nichols
Nov 14 '07 #10

P: n/a
Hi All,

Well Thanks for your answers, but you know what this question is asked
as one of interview questions, and output was given as 10,15,200,150.
There was no answer which says, undefined behavior, for the first
moment even i had the same impression, but to them what matters is
whether your answer is right/wrong. But any how, this was good
learning point for me.

Thanks,

Regards,
Raghu Kumar K
Nov 16 '07 #11

P: n/a
On Nov 16, 6:44 pm, raghukumar <raghukumar.r...@gmail.comwrote:
Well Thanks for your answers, but you know what this question is asked
as one of interview questions, and output was given as 10,15,200,150.
There was no answer which says, undefined behavior, for the first
moment even i had the same impression, but to them what matters is
whether your answer is right/wrong.
What about - "none of the above". If this was not option, then
the questionnaire was flawed.

Werner
Nov 16 '07 #12

P: n/a
What about - "none of the above". If this was not option, then
the questionnaire was flawed.
Well, nothing like this was mentioned. ... :)
only four options..

Thanks,
Nov 17 '07 #13

This discussion thread is closed

Replies have been disabled for this discussion.