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

StackOverflow https://stackoverflow.com/questions/16652550

  •  30-05-2022
  •  | 
  •  

Frage

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?

War es hilfreich?

Lösung

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).

Andere Tipps

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.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top