1

I try to use the get-address operator "&" to get the addresses of some member variables of struct type demo.
But strange thing happens if the member type is char.
I don't know what's happening. Can anyone help me and explain why? here is my code:

#include <iostream>
using namespace std;

struct demo{
    int a;
    float b;
    char c;
    char d;
    char e;
};

int main(){

    demo s;
    s.a = 0;
    s.b = 0.1;
    s.c = 'c';
    s.d = 'd';
    s.e = 'e';

    cout << "address of a:[" <<&s.a <<"]"<< endl;
    cout << "address of b:[" <<&s.b <<"]"<< endl;
    cout << "address of c:[" <<&s.c <<"]"<< endl;
}

I compiled the code with g++ and got the following output:

address of a:[0x7fff96b9f5c0]
address of b:[0x7fff96b9f5c4]
address of c:[cde]

The addresses of s.a and s.b are correctly printed. But why the address of s.c is [cde]? It seems that when the type is char, &s.c returns some values in(may be near)that memory address. Dose it has something to do with memory alignment in structs ?

Ysharp
  • 31
  • 3
  • You are right. Sorry for not searching the problem thoroughly. Thanks very much, that post explained very well. – Ysharp Nov 16 '13 at 04:17

1 Answers1

1

That's the thing about characters, it's trying to print the character that at's the location of s.c. That's why it prints out "cde", because the immediate characters after s.c are 'd' and 'e' and then most likely a terminating 0.

You can still get the address with &s.c and give it to a pointer. The pointer's value will be whatever address is a few bytes after float b.

To fix this you can cast the address &s.c to another data type, like int.
That way cout won't try to print out the actual characters.

This can be done like so:

cout << "address of c:[" << (int*)((int)&s.c) << "]"<< endl;

Here we cast the address to an integer, and then back into a pointer so that when we print it it's in the nice pointer-y hex format.
I compiled the new code and got these results:

address of a:[0x28fed4]
address of b:[0x28fed8]
address of c:[0x28fedc]
Radnyx
  • 210
  • 2
  • 14
  • 3
    The inner cast to `int` is incorrect, and platform-dependant at-best. At worst it will be outright wrong if `int` is not *identical* to a `char*` in size. Not going into the strict-aliasing diatribe, a proper cast for this is `static_cast(&s.c)`. Just `void*` i.e. `static_cast(&s.c)` will work as well, but I prefer `const` as it eliminates accidental casts from addresses of `const` variables. – WhozCraig Nov 16 '13 at 04:48
  • I think casting char* to const void* type is a great idea, I tried it and it worked! Thank you all very much~~ – Ysharp Nov 16 '13 at 05:03