473,508 Members | 2,267 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Problem: references mess up inheritance. Doesn't make sense.

Problem: If I inherit an object B from A and use references in B to
data in A, arrays of B objects which are pointed to by an A pointer
causes "EXC_BAD_ACCESS" errors at the point shown in the code below.
Removing the references cures the problem. Throughout, the correct
virtural functions are called.

The code is dirt simple (below). Can anyone explain why reference in
the interited object ruin the array structure in some way that causes a
crash? If I remove the references in B (w and z) and their
initialization in the B creator, the code runs fine and the correct
(virtual) B::prn_data() is called.

I'm running gcc 3.3 on a Mac OS X 10.3.9 Powerbook using Xcode. But
this seems like a generic C++ question.

Thanks for any help.

--- The code - header -----------------------------------

// junk.h

class A {
public:
float x,y;

A();
virtual void prn_data();
};

class B: public A {
public:
float &w,&z;

B();
virtual void prn_data();
};

--- The code - source .cpp -----------------------------------

// ---- Junk Test --------------------------
void junktest() {

A *pb=new B[2]; // NOTE: the pointer is of type A.

pb[0].prn_data();
pb[1].prn_data(); // <--- ERROR here
}

// --- A Creator -----------------
A::A() {
x=1.0; y=2.0;
}
// Print data -- virtual
void A::prn_data() {
printf("In A\n");
}

// --- B Creator -----------------
B::B():A(), w(x), z(y)
{
}
// Print data
void B::prn_data() {
printf("In B\n");
A::prn_data();
}

-- Lou Pecora (my views are my own) REMOVE THIS to email me.
Aug 15 '05 #1
8 1444
Lou Pecora wrote:
Problem: If I inherit an object B from A and use references in B to
data in A, arrays of B objects which are pointed to by an A pointer
causes "EXC_BAD_ACCESS" errors at the point shown in the code below.
Removing the references cures the problem. Throughout, the correct
virtural functions are called.

The code is dirt simple (below).
Please next time do not indicate different files. Post your code as one
contiguous text -- that's what it should be. Everybody reading c.l.c++
should be able to simply copy your code from the message and paste it in
a text editor, save it as a file, compile it [, run it] and see the same
thing you see.
Can anyone explain why reference in
the interited object ruin the array structure in some way that causes a
crash?
No, I cannot explain why behaviour changes without going into compiler-
specific stuff (which is OT). The behaviour is _undefined_ either way.
It just looks like the desired behaviour when you have the derived class
object add no data. Change the references to be regular 'float' values
and you will have the same crash, most likely. Again, the behaviour is
undefined.

The reason the behaviour is undefined is simple: you treat an array of
derived class objects as if it were an array of the base class objects.
You can't do that and expect your program to work.
If I remove the references in B (w and z) and their
initialization in the B creator, the code runs fine and the correct
(virtual) B::prn_data() is called.

I'm running gcc 3.3 on a Mac OS X 10.3.9 Powerbook using Xcode. But
this seems like a generic C++ question.

Thanks for any help.

--- The code - header -----------------------------------

// junk.h

class A {
public:
float x,y;

A();
virtual void prn_data();
};

class B: public A {
public:
float &w,&z;

B();
virtual void prn_data();
};

--- The code - source .cpp -----------------------------------

// ---- Junk Test --------------------------
void junktest() {
Shouldn't this function be 'int main()'?

A *pb=new B[2]; // NOTE: the pointer is of type A.
An array of _derived_ class objects is accessed through a pointer to
the base class. This is simply _undefined_behaviour_.

pb[0].prn_data();
pb[1].prn_data(); // <--- ERROR here
Of course it is. The offset to the object is calculated based on the
size of A, not on the _real_ size. pb[1] is presumed to be located
in the wrong place.
}

// --- A Creator -----------------
A::A() {
x=1.0; y=2.0;
Prefer initialisation over assignment. See FAQ.
}
// Print data -- virtual
void A::prn_data() {
printf("In A\n");
'printf' undefined. Did you forget to include some standard header?
}

// --- B Creator -----------------
B::B():A(), w(x), z(y)
{
}
// Print data
void B::prn_data() {
printf("In B\n");
A::prn_data();
}


V
Aug 15 '05 #2
In article <v4******************@newsread1.mlpsca01.us.to.ver io.net>,
Victor Bazarov <v.********@comAcast.net> wrote:
Lou Pecora wrote:
Problem: If I inherit an object B from A and use references in B to
data in A, arrays of B objects which are pointed to by an A pointer
causes "EXC_BAD_ACCESS" errors at the point shown in the code below.
Removing the references cures the problem. Throughout, the correct
virtural functions are called.

The code is dirt simple (below).
Please next time do not indicate different files. Post your code as one
contiguous text -- that's what it should be. Everybody reading c.l.c++
should be able to simply copy your code from the message and paste it in
a text editor, save it as a file, compile it [, run it] and see the same
thing you see.


Yes, I left out the main and the includes. Very sorry.
> Can anyone explain why reference in
the interited object ruin the array structure in some way that causes a
crash?


No, I cannot explain why behaviour changes without going into compiler-
specific stuff (which is OT). The behaviour is _undefined_ either way.
It just looks like the desired behaviour when you have the derived class
object add no data. Change the references to be regular 'float' values
and you will have the same crash, most likely. Again, the behaviour is
undefined.


You are right. It had nothing to do with the reference idea. Regular
data crashed it, too.
The reason the behaviour is undefined is simple: you treat an array of
derived class objects as if it were an array of the base class objects.
You can't do that and expect your program to work.

Yes, I see what you mean. I was heading toward that idea. You got
there a lot faster than I. I changed the implementation to one of an
array of pointers to my base class, but then used "new" to have each
array component point to a derived class. Adjusting the code for
pointer rather than object access made it work.

Thank you for your insight.

-- Lou Pecora (my views are my own) REMOVE THIS to email me.
Aug 15 '05 #3

"Lou Pecora" <pe**********@THISanvil.nrl.navy.mil> wrote in message
news:pe********************************@ra.nrl.nav y.mil...
Problem: If I inherit an object B from A and use references in B to
data in A, arrays of B objects which are pointed to by an A pointer
causes "EXC_BAD_ACCESS" errors at the point shown in the code below.
Removing the references cures the problem. Throughout, the correct
virtural functions are called.

The code is dirt simple (below). Can anyone explain why reference in
the interited object ruin the array structure in some way that causes a
crash? If I remove the references in B (w and z) and their
initialization in the B creator, the code runs fine and the correct
(virtual) B::prn_data() is called.

I'm running gcc 3.3 on a Mac OS X 10.3.9 Powerbook using Xcode. But
this seems like a generic C++ question.

Thanks for any help.

--- The code - header -----------------------------------

// junk.h

class A {
public:
float x,y;

A();
virtual void prn_data();
};

class B: public A {
public:
float &w,&z;

B();
virtual void prn_data();
};

--- The code - source .cpp -----------------------------------

// ---- Junk Test --------------------------
void junktest() {

A *pb=new B[2]; // NOTE: the pointer is of type A.

pb[0].prn_data();
pb[1].prn_data(); // <--- ERROR here
}

// --- A Creator -----------------
A::A() {
x=1.0; y=2.0;
}
// Print data -- virtual
void A::prn_data() {
printf("In A\n");
}

// --- B Creator -----------------
B::B():A(), w(x), z(y)
{
}
// Print data
void B::prn_data() {
printf("In B\n");
A::prn_data();
}

-- Lou Pecora (my views are my own) REMOVE THIS to email me.


Lou,

your problem is here:::

A *pb=new B[2]; // NOTE: the pointer is of type A.

pb[0].prn_data();
pb[1].prn_data(); // <--- ERROR here

You are indexing in consistently - pb is an array of A's, but you actually
put 'B's into it,
when you index at location 1, note that A and B's have different sizes, ,
the address you access is not the address of a valid object and so Kaboom!!
Very Nasty!

Probably you won't see this crash if you didn't invoke the virtual member
functions. When you
try to invoke the virtual functions, the computation to locate the virtual
function pointer will be
hopeless hosed up so you will try to use some invalid address in memory as
the function address..

dave


Aug 16 '05 #4
Dave Townsend wrote:
"Lou Pecora" <pe**********@THISanvil.nrl.navy.mil> wrote in message
news:pe********************************@ra.nrl.nav y.mil...
Problem: If I inherit an object B from A and use references in B to
data in A, arrays of B objects which are pointed to by an A pointer
causes "EXC_BAD_ACCESS" errors at the point shown in the code below.
Removing the references cures the problem. Throughout, the correct
virtural functions are called.

The code is dirt simple (below). Can anyone explain why reference in
the interited object ruin the array structure in some way that causes a
crash? If I remove the references in B (w and z) and their
initialization in the B creator, the code runs fine and the correct
(virtual) B::prn_data() is called.

I'm running gcc 3.3 on a Mac OS X 10.3.9 Powerbook using Xcode. But
this seems like a generic C++ question.

Thanks for any help.

--- The code - header -----------------------------------

// junk.h

class A {
public:
float x,y;

A();
virtual void prn_data();
};

class B: public A {
public:
float &w,&z;

B();
virtual void prn_data();
};

--- The code - source .cpp -----------------------------------

// ---- Junk Test --------------------------
void junktest() {

A *pb=new B[2]; // NOTE: the pointer is of type A.

pb[0].prn_data();
pb[1].prn_data(); // <--- ERROR here
}

// --- A Creator -----------------
A::A() {
x=1.0; y=2.0;
}
// Print data -- virtual
void A::prn_data() {
printf("In A\n");
}

// --- B Creator -----------------
B::B():A(), w(x), z(y)
{
}
// Print data
void B::prn_data() {
printf("In B\n");
A::prn_data();
}

-- Lou Pecora (my views are my own) REMOVE THIS to email me.


Lou,

your problem is here:::

A *pb=new B[2]; // NOTE: the pointer is of type A.

pb[0].prn_data();
pb[1].prn_data(); // <--- ERROR here

You are indexing in consistently - pb is an array of A's, but you actually
put 'B's into it,
when you index at location 1, note that A and B's have different sizes, ,
the address you access is not the address of a valid object and so Kaboom!!
Very Nasty!

Probably you won't see this crash if you didn't invoke the virtual member
functions. When you
try to invoke the virtual functions, the computation to locate the virtual
function pointer will be
hopeless hosed up so you will try to use some invalid address in memory as
the function address..

dave


just one query:

will this work if i use

(a + 0)->prnt_data() and (a + 1)->prnt_data();
and if not why ???
thanks
rt.

Aug 16 '05 #5
This should work:

#include <iostream>

class A
{
protected:
float x;
float y;
public:
A() : x( 1.0 ), y( 2.0 ) {}
virtual ~A() {}
virtual void prn_data() const { std::cout << "in A prn_data\n"; }
};

class B : public A
{
protected:
float & w;
float & z;
public:
B() : w(x), z(y) {}
virtual void prn_data() const
{
std::cout << "in B::prn_data\n";
A::prn_data();
}
};

int main()
{
B b[2];
A* pb[2];
pb[0] = &b[0];
pb[1] = &b[1];

pb[0].prn_data();
pb[1].prn_data();
}

Aug 16 '05 #6
Lou,

your problem is here:::

A *pb=new B[2]; // NOTE: the pointer is of type A.

pb[0].prn_data();
pb[1].prn_data(); // <--- ERROR here

You are indexing in consistently - pb is an array of A's, but you actually
put 'B's into it,
when you index at location 1, note that A and B's have different sizes, ,
the address you access is not the address of a valid object and so Kaboom!!
Very Nasty!

Probably you won't see this crash if you didn't invoke the virtual member
functions. When you
try to invoke the virtual functions, the computation to locate the virtual
function pointer will be
hopeless hosed up so you will try to use some invalid address in memory as
the function address..

dave


Thank you, Dave. That's it. I switched to arrays of pointers to the
base object which are then pointed to the derived object. That cured
the problem.

-- Lou Pecora (my views are my own) REMOVE THIS to email me.
Aug 16 '05 #7
In article <11*********************@g44g2000cwa.googlegroups. com>,
"Earl Purple" <ea*********@yahoo.com> wrote:
This should work:

#include <iostream>

class A
{
protected:
float x;
float y;
public:
A() : x( 1.0 ), y( 2.0 ) {}
virtual ~A() {}
virtual void prn_data() const { std::cout << "in A prn_data\n"; }
};

class B : public A
{
protected:
float & w;
float & z;
public:
B() : w(x), z(y) {}
virtual void prn_data() const
{
std::cout << "in B::prn_data\n";
A::prn_data();
}
};

int main()
{
B b[2];
A* pb[2];
pb[0] = &b[0];
pb[1] = &b[1];

pb[0].prn_data();
pb[1].prn_data();
}


Thanks, Earl. That's basically what I ended up with. Except I have

pb[0]->prn_data(); etc. in main().

That seems to work for me. pb[0], pb[1] are pointers to B, right?

-- Lou Pecora (my views are my own) REMOVE THIS to email me.
Aug 16 '05 #8
Ram
> just one query:

will this work if i use

(a + 0)->prnt_data() and (a + 1)->prnt_data();
and if not why ???


What is a?

Aug 17 '05 #9

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

Similar topics

0
2027
by: Andreas Suurkuusk | last post by:
Hi, I just noticed your post in the "C# memory problem: no end for our problem?" thread. In the post you implied that I do not how the garbage collector works and that I mislead people. Since...
19
3171
by: Mike Tyka | last post by:
Hello community, i'm fairly new to using the STL but i've been experimenting a bit with it. I tried to derive a new class say MyString from string like so: class MyString: public string{...
30
4517
by: dbuchanan | last post by:
ComboBox databindng Problem == How the ComboBox is setup and used: My comboBox is populated by a lookup table. The ValueMember is the lookup table's Id and the DisplayMember is the text from a...
2
2819
by: Scott Goodwin | last post by:
In the following example: create table parent ( id integer unique not null, name varchar(24) ); create table child ( first_name varchar(256), last_name varchar(256)
2
2085
by: Scott Goodwin | last post by:
The following SQL: create table toinherit ( id integer primary key ); create table leftside ( leftname varchar(64) not null unique ) inherits (toinherit);
31
2868
by: anongroupaccount | last post by:
I have an ABC with a protected member that is a reference to an object of an ABC type: class ABC { public: virtual ~ABC() = 0; protected: AnotherABC& _member; }
9
2943
by: MSDNAndi | last post by:
Hi, I have the following problem with VS 2005 (Professional) and C# 2.0 I will use assembly and namespace synonymously here. I have a class in namespace InheritClass inherit from a baseclass...
2
16395
by: nino9stars | last post by:
Hello, I have just started messing with absolute positioning on webpages, and it definitely let's you do some creative things. Well, after much searching and help, I got the images I was using...
43
2311
by: John | last post by:
Hi This .net is driving me crazy!! In VB6 I had a type which contained a couple of multi-dimentional arrays which i used to create and read records: Type AAA : Array1(10,10,2) as Integer
0
7224
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
7120
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...
0
7380
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
7494
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...
0
4706
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and...
0
3192
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...
0
3180
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
0
1553
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 ...
1
763
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

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.