I'm experimenting with smart pointers and I wrote the code below:
struct Buffer
{
char Data[128];
};
class SmartPtr {
char * dataPtr;
public:
SmartPtr(Buffer& b)
{
dataPtr = b.Data;
}
~SmartPtr()
{
cout << "desctructor called" << endl;
}
void operator=(Buffer & b)
{
dataPtr = b.Data;
}
char*& operator*()
{
return dataPtr;
}
};
I though that when using a pointer of the same type as the type of the first member of a class I can access that member.
What I'm trying to do is accessing dataPtr
by getting the address of the object p
.
I'm expecting p
and dataPtr
to have the same address.
The following code prints garbage.
static Buffer buff;
int main(void)
{
strcpy(buff.Data, "Hello world");
SmartPtr p = buff;
char* s = (char*)&p;
cout << "Data: " << s << endl;
return 0;
}
Output:
Data: Ç☺┴─≈
desctructor called
If I change that to a double pointer I get the expected result
static Buffer buff;
int main(void)
{
strcpy(buff.Data, "Hello world");
SmartPtr p = buff;
char** s = (char**)&p;
cout << "Data: " << *s << endl;
return 0;
}
Output:
Data: Hello world
desctructor called
Is it because with a single pointer I dereference the address of the actual pointer as a variable instead of the address it contains?
CodePudding user response:
In the first code, you are taking the address of p
(and thus the address of p.dataPtr
), casting it to char*
, and then printing it as-is. So, operator<<
is misinterpreting the raw memory of p
itself as-if it were a null-terminated string, which it is not, so you get garbage.
In the second code, you are taking the address of p
(and thus the address of p.dataPtr
), casting it to char**
, dereferencing it to access its value as a char*
, and then printing that. So, operator<<
is printing the data that p.dataPtr
is pointing at as a null-terminated string, which it is, so you get the correct result.