473,883 Members | 1,692 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

pointer arithmetic with inheritance

ceo
Hi,

Following is a program that doesn't give the expected output, not sure
what's wrong here. I'm adding the size of derived class to the base
class pointer to access the next element in the array. Why does bp
point to some address that is not &d[1]?

Please clarify.

Thanks,
Ceo

#include <iostream>
using namespace std;

class base {
int i;
public:
void set_i(int num) { i=num; }
int get_i() { return i; }
};

class derived: public base {
int j;
public:
void set_j(int num) {j=num;}
int get_j() {return j;}
};

int main()
{
base *bp;
derived d[2];

bp = d;

d[0].set_i(1);
d[1].set_i(2);

cout << "\n sizeof (base): " << sizeof(base) << endl;
cout << "\n sizeof (derived): " << sizeof(derived) << endl << endl;

cout << " d[0] addr: " << &d[0] << endl;
cout << " d[1] addr: " << &d[1] << endl;
cout << " bp addr: " << bp << endl << endl;

cout << " i = " << bp->get_i() << endl << endl;
bp = bp + sizeof(derived) ;
cout << " bp addr: " << bp << endl << endl;
cout << " i = " << bp->get_i() << endl << endl;

return 0;
}

output on my machine:
--------------------
sizeof (base): 4

sizeof (derived): 8

d[0] addr: 0012FF6C
d[1] addr: 0012FF74
bp addr: 0012FF6C

i = 1

bp addr: 0012FF8C

i = 3149472

Jul 23 '05 #1
8 2194

"ceo" <ce******@gmail .com>, haber iletisinde sunlari
yazdi:11******* *************** @z14g2000cwz.go oglegroups.com. ..
Hi,

Following is a program that doesn't give the expected output, not sure
what's wrong here. I'm adding the size of derived class to the base
class pointer to access the next element in the array. Why does bp
point to some address that is not &d[1]?

Please clarify.

Thanks,
Ceo

#include <iostream>
using namespace std;

class base {
int i;
public:
void set_i(int num) { i=num; }
int get_i() { return i; }
};

class derived: public base {
int j;
public:
void set_j(int num) {j=num;}
int get_j() {return j;}
};

int main()
{
base *bp;
derived d[2];

bp = d;

d[0].set_i(1);
d[1].set_i(2);

cout << "\n sizeof (base): " << sizeof(base) << endl;
cout << "\n sizeof (derived): " << sizeof(derived) << endl << endl;

cout << " d[0] addr: " << &d[0] << endl;
cout << " d[1] addr: " << &d[1] << endl;
cout << " bp addr: " << bp << endl << endl;

cout << " i = " << bp->get_i() << endl << endl;
bp = bp + sizeof(derived) ;
You have a problem here.
bp is pointing to base which is of size 4.
bp = bp + 8 is equal to bp = bp + 4*8 = bp +32;

this should be OK:
bp = (base*)((size_t )bp + sizeof(derived) );
cout << " bp addr: " << bp << endl << endl;
cout << " i = " << bp->get_i() << endl << endl;

return 0;
}

output on my machine:
--------------------
sizeof (base): 4

sizeof (derived): 8

d[0] addr: 0012FF6C
d[1] addr: 0012FF74
bp addr: 0012FF6C

i = 1

bp addr: 0012FF8C

i = 3149472

Jul 23 '05 #2

ceo wrote:
Hi,

Following is a program that doesn't give the expected output, not sure what's wrong here. I'm adding the size of derived class to the base
class pointer to access the next element in the array. Why does bp
point to some address that is not &d[1]?

Please clarify.

Thanks,
Ceo

#include <iostream>
using namespace std;

class base {
int i;
public:
void set_i(int num) { i=num; }
int get_i() { return i; }
};

class derived: public base {
int j;
public:
void set_j(int num) {j=num;}
int get_j() {return j;}
};

int main()
{
base *bp;
derived d[2];

bp = d;

d[0].set_i(1);
d[1].set_i(2);

cout << "\n sizeof (base): " << sizeof(base) << endl;
cout << "\n sizeof (derived): " << sizeof(derived) << endl << endl;

cout << " d[0] addr: " << &d[0] << endl;
cout << " d[1] addr: " << &d[1] << endl;
cout << " bp addr: " << bp << endl << endl;

cout << " i = " << bp->get_i() << endl << endl;
bp = bp + sizeof(derived) ;
cout << " bp addr: " << bp << endl << endl;
cout << " i = " << bp->get_i() << endl << endl;

return 0;
}

output on my machine:
--------------------
sizeof (base): 4

sizeof (derived): 8

d[0] addr: 0012FF6C
d[1] addr: 0012FF74
bp addr: 0012FF6C

i = 1

bp addr: 0012FF8C

i = 3149472


You can not use pointer arithmetic using a base class pointer that
points to a derive class.

You can however use a pointer to a pointer to get pointer arithmetic to
work with a base class type.
Example:

class Base
{
public:
Base():m_x(999) {}
virtual void OutPutData()=0;
int m_x;
};

class SubClass : public Base
{
public:
SubClass():m_y( 1234){}
void OutPutData(){
cout << m_y << endl;
}
long m_y;
};

int main(int argc, char* argv[])
{
Base *b[2];
SubClass s[2];

b[0] = &s[0];
b[1] = &s[1];

Base **ppBase = b;

(*ppBase)->OutPutData() ;

++ppBase; //Pointer arithmetic

(*ppBase)->OutPutData() ;
*************** *************** *************** *************** ************
David Maisonave :-}
Top ten member of C++ Expert Exchange.
http://experts-exchange.com/Programm...ges/Cplusplus/

Jul 23 '05 #3
ceo wrote:

Hi,

Following is a program that doesn't give the expected output, not sure
what's wrong here. I'm adding the size of derived class to the base
class pointer to access the next element in the array. Why does bp
point to some address that is not &d[1]?
Because of pointer arithmetic.
Pointer arithmetic automatically multiplies with the size
of the dereferenced pointer type (Thats hard to describe,
but actually is very simple). So what the compiler has
compiled would be the equivalent to:
bp = bp + sizeof(derived) ;


uncigned char* pBasePtr = bp;
pBasePtr = pBasePtr + ( sizeof( derived ) * sizeof( *pBasePtr ) );
bp = (base*)pBasePtr ;

You may now figure out on your own, why this will not get the
result you expect.

--
Karl Heinz Buchegger
kb******@gascad .at
Jul 23 '05 #4
ceo
>> bp = (base*)((size_t ) bp + sizeof(derived) );

Thanks, this works. I got the idea. The following worked too.

bp = bp + sizeof(derived)/sizeof(base);

Jul 23 '05 #5

"ceo" <ce******@gmail .com>, haber iletisinde sunlari
yazdi:11******* **************@ z14g2000cwz.goo glegroups.com.. .
bp = (base*)((size_t ) bp + sizeof(derived) );


Thanks, this works. I got the idea. The following worked too.

bp = bp + sizeof(derived)/sizeof(base);

Just by chance. Add a variable in base or derived, you will see why.
Jul 23 '05 #6
ceo wrote:
bp = (base*)((size_t ) bp + sizeof(derived) );


However, it's not guaranteed that size_t is large enough to store a
pointer value. Use (char*).

Thanks, this works. I got the idea. The following worked too.

bp = bp + sizeof(derived)/sizeof(base);


Only by accident. If sizeof(base) is not a divisor of sizeof(derived)
the value will be too small.

Bottom line: don't play this sort of game. There are too many ways to go
astray.

--

Pete Becker
Dinkumware, Ltd. (http://www.dinkumware.com)
Jul 23 '05 #7
Pete Becker wrote:
ceo wrote:
bp = (base*)((size_t ) bp + sizeof(derived) );

However, it's not guaranteed that size_t is large enough to store a
pointer value. Use (char*).

Bottom line: don't play this sort of game. There are too many ways to

go astray.


I think the behaviour is still undefined, and a bounds-checking
implementation could decide that you have exceeded the bounds of
*bp .

Perhaps this would be better:
bp = dynamic_cast<de rived *>(bp) + 1;

I guess a good compiler would optimise this dynamic cast
to happen at compile-time for this particular example,
so there would be no performance penalty.

Jul 23 '05 #8
Old Wolf wrote:
Pete Becker wrote:
ceo wrote:
>bp = (base*)((size_t ) bp + sizeof(derived) );
However, it's not guaranteed that size_t is large enough to store a
pointer value. Use (char*).

Bottom line: don't play this sort of game. There are too many ways to


go
astray.

I think the behaviour is still undefined, and a bounds-checking
implementation could decide that you have exceeded the bounds of
*bp .


I don't see it.

Perhaps this would be better:
bp = dynamic_cast<de rived *>(bp) + 1;


No, base has no virtual functions.

--

Pete Becker
Dinkumware, Ltd. (http://www.dinkumware.com)
Jul 23 '05 #9

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

22
12763
by: Alex Fraser | last post by:
From searching Google Groups, I understand that void pointer arithmetic is a constraint violation, which is understandable. However, generic functions like qsort() and bsearch() must in essence do exactly this, and similarly generic functions seem to have useful applications. In a few posts I read, it was suggested to avoid void pointer arithmetic by casting to a char pointer, and performing arithmetic on that (in multiples of...
6
2298
by: Francois Grieu | last post by:
Are these programs correct ? #include <stdio.h> unsigned char a = {1,2}; int main(void) { unsigned char j; for(j=1; j<=2; ++j) printf("%u\n", *( a+j-1 )); return 0; }
3
2213
by: randomtalk | last post by:
hello everyone! Well, recently i've been trying to pick up c and see what is pointer all about (been programming in lisp/python for the better part of my last two years).. mmm.. I'm currently reading The C Programming Language Second Edition.. When i hit on pointer arithmetic example, i have no idea what's happening, hopefully some of you could alleviate my confusion, so here goes:
27
9004
by: Erik de Castro Lopo | last post by:
Hi all, The GNU C compiler allows a void pointer to be incremented and the behaviour is equivalent to incrementing a char pointer. Is this legal C99 or is this a GNU C extention? Thanks in advance. Erik
7
528
by: barikat | last post by:
int a; int *Ptr1, *Ptr2; Ptr1 = a; Ptr1++; Ptr2 = a; printf("Ptr1 : %p\n", Ptr1); printf("Ptr2 : %p\n\n", Ptr2);
26
3076
by: Bill Reid | last post by:
Bear with me, as I am not a "professional" programmer, but I was working on part of program that reads parts of four text files into a buffer which I re-allocate the size as I read each file. I read some of the items from the bottom up of the buffer, and some from the top down, moving the bottom items back to the new re-allocated bottom on every file read. Then when I've read all four files, I sort the top and bottom items separately...
41
3707
by: Summercool | last post by:
Can we confirm the following? also someone said, Java also has "reference" like in C++, which is an "implicit pointer": Pointer and Reference --------------------- I am starting to see what pointer and reference are and how they relate to each other.
19
3916
by: =?iso-8859-1?b?VG9t4XMg0yBoyWlsaWRoZQ==?= | last post by:
Coming originally from C++, I used to do the likes of the following, using a pointer in a conditional: void Func(int *p) { if (p) { *p++ = 7; *p++ = 8;
25
2029
by: Ioannis Vranos | last post by:
Are the following codes guaranteed to work always? 1. #include <iostream> inline void some_func(int *p, const std::size_t SIZE) {
0
9778
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
11112
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
10405
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
1
7959
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
5784
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
5980
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
4602
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
4205
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
3228
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.