简体   繁体   中英

Why is the pointer value in the function different to the one passed in as an argument?

I have the following constructor:

MutexWrapper::MutexWrapper(Mutex * pMutex)
{
  DebugPrint("0x%x", pMutex); // displays 0x1f83e54
}

And it gets called in the following function:

void OnReviewBuffer_Callback( void * pUserData )
{
  ReviewBuffer * thePointer = (ReviewBuffer *) pUserData;

  DebugPrint("0x%x", thePointer); // this displays 0x1f83e48

  MutexWrapper theMutexWrapper(thePointer);
}

Unfortunately I can't provide the entire definition of ReviewBuffer - but I hope the below is enough:

class ReviewBuffer  : public StreamConsumer_Base, public Mutex
{
  ...
};

The problem is that when I print out thePointer I get 0x1f83e48 , but the value printed from inside the constructor is 0x1f83e54 .

Why are the pointer values different - is this something to do with pass by value passing in a copy of the pointer?

Your class ReviewBuffer uses multiple inheritance:

class ReviewBuffer  : public StreamConsumer_Base, public Mutex
{
  ...
};

The internal layout of the class (probably*) looks like this:

Offset 0    class StreamConsumer_Base
            ... contents of that class (12 bytes including alignment: 0x1f83e54 - 0x1f83e48)
Offset 12   class Mutex
            ... contents of that class (unknown size)

(*) probably because nothing in the standard mandates this. This is just the usual way compilers implement it.

When you initially print thePointer , it points to the ReviewBuffer object ie. offset 0 of the class. But when you pass it to your function, the pointer automatically gets adjusted by the compiler to point to the Mutex part of ReviewBuffer . Since that Mutex part is at offset 12, the value of the pointer cannot be the same (think about it: if it was the same, it would not point to a Mutex but to either a ReviewBuffer or a StreamConsumer_Base ).

Your non-default constructor MutexWrapper::MutexWrapper takes a Mutex* pointer as an argument. Your function OnReviewBuffer_Callback casts the provided void* pointer to a ReviewBuffer* pointer. The only way you can pass that ReviewBuffer* pointer as an argument to MutexWrapper::MutexWrapper(Mutex*) is if ReviewBuffer is a derived class of Mutex . If ReviewBuffer also inherits from other classes, downcasting a ReviewBuffer* pointer to a Mutex* pointer may result in a pointer with a different address than the original. That is exactly what's going on, based on the latest edit. ReviewBuffer uses multiple inheritance.

In C++ as in Java, pointer are passed by value. Pass-by-reference is a misnomer.

Of course, pointer pointing to the same address variable, it looks like the whole is passed-by-reference, but...isn't.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM