class pointer value modified

C

cweisbrod

All,

I'm seeing something very strange and was hoping someone might have
some insight into the cause of what I'm seeing. I have the following
scenario:

Platform: Microsoft Windows XP Pro, Visual Studio 2005

Code:

/////////////////////
class Parent
{
int parentData;
};

class Child : public Parent
{
char childData1;
int childData2;
};

void theFunction(Parent* inParent)
{
printf("inParent = %X\n", inParent);
}

int _tmain(int argc, _TCHAR* argv[])
{
Child* theChild = new Child;
if (theChild)
{
printf("theChild = %X\n", theChild);
theFunction(theChild);
delete theChild;
}

return 0;
}
/////////////////////

I get the following output:

theChild = 27373F0
inParent = 27373F4

Why would the address be different in the theFunction?

Thanks for any replies at all.
 
V

Victor Bazarov

I'm seeing something very strange and was hoping someone might have
some insight into the cause of what I'm seeing. I have the following
scenario:

Platform: Microsoft Windows XP Pro, Visual Studio 2005

Code:

/////////////////////
class Parent
{
int parentData;
};

class Child : public Parent

I think 'Child' is a bad misnomer. A child is not a parent,
but your public inheritance implies that. If you just used
those names for this example, use 'Base' and 'Derived' next
time.
{
char childData1;
int childData2;
};

void theFunction(Parent* inParent)
{
printf("inParent = %X\n", inParent);
}

int _tmain(int argc, _TCHAR* argv[])

(a) Try to minimize the use of non-standard constructs in your
posts here.

(b) If you don't use 'argc' or 'argv', why define your main to
use them?
{
Child* theChild = new Child;
if (theChild)
{
printf("theChild = %X\n", theChild);
theFunction(theChild);
delete theChild;
}

return 0;
}
/////////////////////

I get the following output:

theChild = 27373F0
inParent = 27373F4

Why would the address be different in the theFunction?

Why not? They are different objects. Essentially, in C++
inheritance derived class objects _contain_ base class objects
in them. The memory location of the base class sub-object is
not necessarily the same as the object that contains it.

V
 
S

Salt_Peter

All,

I'm seeing something very strange and was hoping someone might have
some insight into the cause of what I'm seeing. I have the following
scenario:

Platform: Microsoft Windows XP Pro, Visual Studio 2005

Code:

/////////////////////
class Parent
{
int parentData;
};

class Child : public Parent
{
char childData1;
int childData2;
};

void theFunction(Parent* inParent)
{
printf("inParent = %X\n", inParent);
}

int _tmain(int argc, _TCHAR* argv[])

int main()
{
Child* theChild = new Child;
if (theChild)
{
printf("theChild = %X\n", theChild);
theFunction(theChild);
delete theChild;
}

return 0;
}
/////////////////////

I get the following output:

theChild = 27373F0
inParent = 27373F4

Why would the address be different in the theFunction?

Because you are accessing different parts of the same object. Note that
you are passing a pointer to child to a function taking a pointer to
its parent. So even if the addresses were the same, you would still be
accessing the child through its parent pointer. Use sizeof(...) and
calculate the child's location and the parent's location in memory if
you doubt that.

Incidentally, i'ld strongly suggest using constants and references.

void theFunction(const Parent* const p_parent) { ... }
or
void theFunction(const Parent& r_parent) { ... }

Note:
const Parent* p_parent; // is a mutable pointer!!
 
E

Eric VW

I think this is a Visual Studio problem because I ran the code in g++
3.4.6-3 and i got:

theChild = 804A008
inParent = 804A008
 
C

cweisbrod

I think 'Child' is a bad misnomer. A child is not a parent,
but your public inheritance implies that. If you just used
those names for this example, use 'Base' and 'Derived' next
time.
That doesn't answer my question.
(b) If you don't use 'argc' or 'argv', why define your main to
use them?
That doesn't answer my question, either.

I read this group a lot and I'm really discouraged by people who reply
to posts just to critique other people's code when that is not what has
been asked for. STOP IT! It's just an example to illustrate my issue.
Who cares what the name of the class is? Would A and B (which are used
VERY frequently in this context) be any better? My "Child" inherited my
intolerance for patronization. I'm their "Parent". It's a perfectly
reasonable way to name two classes that use inheritance.
Why not? They are different objects. Essentially, in C++
inheritance derived class objects _contain_ base class objects
in them. The memory location of the base class sub-object is
not necessarily the same as the object that contains it.

Theoretically, true. But in practice, I've never seen a compiler
organize an inherited class in memory such that the memory address of
the base class is different from the memory address of the derived
class. I use four different C++ compilers (Microsoft, CodeWarrior
(Mac/Windows), gcc 4.0.1) on two different platforms and the derived
and base memory addresses (in my experience) are always identical.

It is disturbing me that all of a sudden, my compiler is organizing
class instances in memory in a significantly different manner (in one
particular portion of my code).
 
V

Victor Bazarov

That doesn't answer my question.

So damn what? It addresses a deficiency in your code.
That doesn't answer my question, either.

It's not intended to. You clutter your code with unneeded objects
and I pointed it out.
I read this group a lot and I'm really discouraged by people who reply
to posts just to critique other people's code when that is not what
has been asked for. STOP IT!

Don't shout please. I reply in the manner and content I deem
necessary. I owe nothing to you. If you don't like my replies,
killfile me. Like I most likely will killfile you.
It's just an example to illustrate my
issue. Who cares what the name of the class is? Would A and B (which
are used VERY frequently in this context) be any better? My "Child"
inherited my intolerance for patronization. I'm their "Parent". It's
a perfectly reasonable way to name two classes that use inheritance.


Theoretically, true. But in practice, I've never seen a compiler
organize an inherited class in memory such that the memory address of
the base class is different from the memory address of the derived
class.

I use four different C++ compilers (Microsoft, CodeWarrior
(Mac/Windows), gcc 4.0.1) on two different platforms and the derived
and base memory addresses (in my experience) are always identical.

Again, so?
It is disturbing me that all of a sudden, my compiler is organizing
class instances in memory in a significantly different manner (in one
particular portion of my code).

What's disturbing is that you seem to be relying on some particular
layout of your classes which has never been guaranteed by the language.

V
 
F

Frederick Gotham

I read this group a lot and I'm really discouraged by people who reply
to posts just to critique other people's code when that is not what has
been asked for. STOP IT!


You might want to find another newsgroup so.

It's just an example to illustrate my issue.
Who cares what the name of the class is? Would A and B (which are used
VERY frequently in this context) be any better? My "Child" inherited my
intolerance for patronization. I'm their "Parent". It's a perfectly
reasonable way to name two classes that use inheritance.


Let's say there's a school parent-teacher meeting on. Here's the function
we use to meet Mr Smith.

void MeetMrSmith(Parent &);

But watch how we can use it:

int main()
{
Child chd;

MeetMrSmith(chd);
}

A child is not a parent, it does not expand on what a parent is, therefore
it's not a good choice of inheritance. Something like the following would
be more appropriate:

class Child {};

class Parent : Child {
public:

Child &GiveBirth() { return *new Child; }
};

class GrandParent : public Parent {}

Theoretically, true. But in practice, I've never seen a compiler
organize an inherited class in memory such that the memory address of
the base class is different from the memory address of the derived
class. I use four different C++ compilers (Microsoft, CodeWarrior
(Mac/Windows), gcc 4.0.1) on two different platforms and the derived
and base memory addresses (in my experience) are always identical.


Multiple Inheritance does some funky stuff.
 
V

Victor Bazarov

Frederick Gotham wrote:
[missing the origins of the quotation]

You should consider fixing your newsreader so others would know whom
you are quoting...
Multiple Inheritance does some funky stuff.

Yes, but in the original example there was none (although looking back
at it I doubt that it was the exact code compiled, 'printf' is not
defined in it).

V
 
F

Frederick Gotham

Victor Bazarov:
You should consider fixing your newsreader so others would know whom
you are quoting...


If the person doesn't provide a name, my newsreader just ignores it. I
suppose I could set it to use their e-mail address instead, but I'm too lazy
to go through my newsreader setup just to cater for someone who can't even
provide a name.
 
A

Alf P. Steinbach

* Victor Bazarov:
Contrary to popular belief, it's very common that a compiler is such that in

pDerived = &o;
pBase = pDerived;

the two pointer values can easily be physically different, although
comparing as equal and logically referring to the same object.

Which means that

pDerived = &o;
pVoid = pDerived;
pBase = static_cast<Base*>( pVoid );

is a bug waiting to happen, if it isn't one already.

Consider

#include <iostream>
#include <ostream>

struct Base { int x; };
struct Derived: Base { int y; virtual ~Derived() {} };

void display( void* p ) { std::cout << p << std::endl; }

int main()
{
Derived o;

Derived* pDerived = &o;
Base* pBase1 = pDerived;
void* pVoid = pDerived;
Base* pBase2 = static_cast<Base*>( pVoid );

display( pDerived );
display( pBase1 );
display( pVoid );
display( pBase2 );
}

With MSVC 7.1 this produces, for one particular run,

0012FF4C
0012FF50
0012FF4C
0012FF4C

where the last value is an invalid pointer.
 
J

Jack Klein

Victor Bazarov:



If the person doesn't provide a name, my newsreader just ignores it. I
suppose I could set it to use their e-mail address instead, but I'm too lazy
to go through my newsreader setup just to cater for someone who can't even
provide a name.

Are you the same "Frederick Gotham" who apologetically promised to be
less arrogant not very long ago?

Try being more thoughtful and considerate.

Your failure to bother setting up your newsreader properly will almost
certainly not bother the OP who doesn't post in the format you prefer.
Most of the time, if it annoys anyone at all, it will be regulars.
Such as Victor who quite rightfully pointed out your lapse in posting
manners.

The fact is that proper attribution of quoted material in responses
you make is your responsibility. If you can't be bothered to do it
correctly for posts whose format you do not like, then don't reply to
them at all.
 
C

cweisbrod

Alf said:
Contrary to popular belief, it's very common that a compiler is such that in

pDerived = &o;
pBase = pDerived;

the two pointer values can easily be physically different, although
comparing as equal and logically referring to the same object.

Which means that

pDerived = &o;
pVoid = pDerived;
pBase = static_cast<Base*>( pVoid );

is a bug waiting to happen, if it isn't one already.

Consider

#include <iostream>
#include <ostream>

struct Base { int x; };
struct Derived: Base { int y; virtual ~Derived() {} };

void display( void* p ) { std::cout << p << std::endl; }

int main()
{
Derived o;

Derived* pDerived = &o;
Base* pBase1 = pDerived;
void* pVoid = pDerived;
Base* pBase2 = static_cast<Base*>( pVoid );

display( pDerived );
display( pBase1 );
display( pVoid );
display( pBase2 );
}

With MSVC 7.1 this produces, for one particular run,

0012FF4C
0012FF50
0012FF4C
0012FF4C

where the last value is an invalid pointer.

Thanks so much. This is exactly the kind of reply I was hoping to see:
An authoritative answer to my question backed up with code. Most
helpful.

Clint Weisbrod.
 
F

Frederick Gotham

Jack Klein:
Your failure to bother setting up your newsreader properly will almost
certainly not bother the OP who doesn't post in the format you prefer.


The format I prefer? The usage of names by which to call people? Haven't
people had names since the Stone Age? I think it's quite an efficienct way of
distinguishing between persons.

Such as Victor who quite rightfully pointed out your lapse in posting
manners.


So far, only Victor and you have taken exception to it.

The fact is that proper attribution of quoted material in responses
you make is your responsibility.


It's a poster's responsibility to provide a name.
 
F

Frederick Gotham

Victor Bazarov:
I think we used to call this "crawling into a bottle" (and
it has nothing to do with alcohol).

Forget I mentioned it. Move on.


Yippie : )
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,773
Messages
2,569,594
Members
45,119
Latest member
IrmaNorcro
Top