Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

why are the addresses of these variables printing as ab@ and b@?

I run the follow code:

    #include <iostream>

    using namespace std;

    typedef struct Test
    {
        char   a;
        char   b;
        int    i;
        double d;
    }Test;

    int main()
    {
        Test test;
        test.a = 'a';
        test.b = 'b';
        test.i = 478;
        test.d = 4.7;

        cout << &test.a << '\n'
             << &test.b << '\n'
             << &test.i << '\n'
             << &test.d << '\n';

        return 0;
    }

The output is:

    ab@
    b@
    0x28fe94
    0x28fe98

At first, i thought it is a result of the precedence between & and ..
But the 0x28fe94 and 0x28fe94 indicate it's not the problem of precedence.
I can figure out what does the ab@ and b@ mean?

like image 219
stamaimer Avatar asked Jan 12 '23 13:01

stamaimer


2 Answers

When you write

 cout << &test.a

because test.a is a char, this will invoke the operator<< (ostream&, const char*) overload, thinking that your char* is a pointer to a C-style string rather than a pointer to just one character. Consequently, the operation will start reading bytes starting at the memory address of &test.a until it finds a null terminator (a zero byte). This happens to print out ab@, since a has value 'a', b has value 'b', and the number 478, on your system, happens to correspond to an @ character followed eventually by a null byte.

If you want to see the numeric addresses of test.a and test.b, cast the pointers to void*s, which will select the operator<< (ostream&, const void*) overload. For example:

cout << static_cast<void*>(&test.a)

Hope this helps!

like image 175
templatetypedef Avatar answered Jan 31 '23 22:01

templatetypedef


It means undefined behaviour. There's a special overload for const char * that prints it as a null-terminated string. Yours has no terminator, so it goes beyond and triggers the aforementioned UB. Fix it with a cast:

std::cout << static_cast<void *>(&test.a) << '\n'
          << static_cast<void *>(&test.b) << '\n'
          << &test.i << '\n'
          << &test.d << '\n';
like image 32
chris Avatar answered Jan 31 '23 22:01

chris