Почему значение указателя в функции отличается от значения, переданного в качестве аргумента?

У меня есть следующий конструктор:

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

И он вызывается в следующей функции:

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

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

MutexWrapper theMutexWrapper(thePointer);
}

К сожалению, я не могу дать полное определение ReviewBuffer — но я надеюсь, что ниже достаточно:

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

Проблема в том, что когда я распечатываю thePointer я получил 0x1f83e48, но значение, напечатанное внутри конструктора: 0x1f83e54,

Почему значения указателя отличаются — это как-то связано с передачей по значению, передаваемой в копии указателя?

2

Решение

Твой класс ReviewBuffer использует множественное наследование:

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

Внутренний макет класса (вероятно, *) выглядит так:

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)

(*) наверное потому что ничто в стандарте не обязывает это. Это просто обычный способ реализации компиляторами.

Когда вы изначально печатаете thePointer, это указывает на ReviewBuffer объект т.е. смещение 0 класса. Но когда вы передаете его в свою функцию, компилятор автоматически корректирует указатель на Mutex часть ReviewBuffer, С тех пор Mutex часть находится со смещением 12, значение указателя не может быть одинаковым (подумайте об этом: если бы оно было одинаковым, оно не указывало бы на Mutex но либо ReviewBuffer или StreamConsumer_Base).

5

Другие решения

Ваш конструктор не по умолчанию MutexWrapper::MutexWrapper занимает Mutex* указатель в качестве аргумента. Ваша функция OnReviewBuffer_Callback бросает предоставленное void* указатель на ReviewBuffer* указатель. Единственный способ передать это ReviewBuffer* указатель в качестве аргумента MutexWrapper::MutexWrapper(Mutex*) если ReviewBuffer является производным классом Mutex, Если ReviewBuffer также наследует от других классов, понижая ReviewBuffer* указатель на Mutex* Указатель может привести к указателю с адресом, отличным от оригинала. Это именно то, что происходит, основываясь на последних изменениях. ReviewBuffer использует множественное наследование.

2

В C ++, как и в Java, указатель передается по значению.
Передача по ссылке является неправильным.

Конечно, указатель указывает на то же адрес переменная, похоже, что все передается по ссылке, но … нет.

-1
По вопросам рекламы [email protected]