How are pointers to data members allocated/stored in memory? - c++

This is one topic that is not making sense to me. Pointers to data members of a class can be declared and used. However,
What is the logic that supports the idea ? [I am not talking about the syntax, but the logic of this feature]
Also,if i understand this correctly, this would imply an indefinite/variable amount of memory being allocated at the pointer initialization as any number of objects may exist at that time. Also, new objects may be created and destroyed during runtime. Hence, in effect, a single statement will cause a large number of allocations/deallocations. This seems rather counter-intuitive as compared to the rest of the language. Or is my understanding of this incorrect ? I dont think there is any other single initialization statement that will implicitly affect program execution as widely as this.
Lastly, how is memory allocated to these pointers ? Where are they placed with respect to objects ? Is it possible to see physical memory addresses of these pointers ?

A single declaration of a pointer to a data member, creates pointers for every object of that class.
No, it does not. A pointer to a member is a special object that is very different from a pointer; it is a lot more similar to an offset. Given a pointer to an object of the class and a member pointer, you'd be able to get the value of a member; without the pointer to an object of a class a pointer to a member is useless.
Questions 2 and 3 stem from the same basic misunderstanding.

A single declaration of a pointer to a data member, creates pointers for every object of that class.
No. It creates a pointer to a member (which can be though of as an offset from the base of object)
You can then use it with a pointer to an object to get that member.
struct S
{
int x;
int y;
};
int S::* ptrToMember = &S::x; // Pointer to a member.
S obj;
int* ptrToData = &obj.x; // Pointer to object
// that happens to be a member
Notice in creating the pointer to a member we don't use an object (we just use the type information). So this pointer is an offset into the class to get a specific member.
You can access the data member via a pointer or object.
(obj.*ptrToMember) = 5; // Assign via pointer to member (requires an object)
*ptrToData = 6; // Assign via pointer already points at object.
Why does this happen as opposed to a single pointer being created to point to only one specific instance of the class ?
That is called a pointer.
A similar but parallel concept (see above).
What is the logic that supports the idea ?
Silly example:
void addOneToMember(S& obj, int S::* member) { (obj.*member) += 1; }
void addOneToX(S& obj) { addOneToMember(obj, &Obj::x);}
void addOneToY(S& obj) { addOneToMember(obj, &Obj::y);}
Also,if i understand this correctly, this would imply an indefinite/variable amount of memory being allocated at the pointer initialization as any number of objects may exist at that time.
No. Because a pointer to a member is just an offset into an object. You still need the actual object to get the value.
Lastly, how is memory allocated to these pointers ?
Same way as other objects. There is nothing special about them in terms of layout.
But the actual layout is implementation defined. So there is no way of answering this question without referring to the compiler. But it is really of no use to you.
Is it possible to see physical memory addresses of these pointers ?
Sure. They are just like other objects.
// Not that this will provide anything meaningful.
std::cout.write(reinterpret_cast<char*>(&ptrToMember), sizeof(ptrToMember));
// 1) take the address of the pointer to member.
// 2) cast to char* as required by write.
// 3) pass the size of the pointer to member
// and you should write the values printed out.
// Note the values may be non printable but I am sure you can work with that
// Also note the meaning is not useful to you as it is compiler dependent.

Internally, for a class that does not have virtual bases, a pointer-to-member-data just has to hold the offset of the data member from the start of an object of that type. With virtual bases it's a bit more complicated, because the location of the virtual base can change, depending on the type of the most-derived object. Regardless, there's a small amount of data involved, and when you dereference the pointer-to-data-member the compiler generates appropriate code to access it.

Related

C++ pointer vs object

Could you please clear up a question for me regarding pointer vs object in C++. I have the below code that has a class called "person" and a list that allows for 100 objects of that class type.
class person {...}
int main {
person* mylist;
mylist = new person[100];
mylist[0].set_name("John")
// ...
}
In this code I can call a method of the class by mylist[0].set_name() meaning (by my understanding) that mylist[0] is an object (hence the . operator to call a method). The code works fine.
I have another project where the "person" class is used as a base class to derive classes "carpenter" and "welder". The derived classes simply overwrite a virtual function called salary in the base "person" class to allow for a different calculation of salary.
person* mylist[100];
mylist[0] = new carpenter;
mylist[0]->set_name("John");
This code works fine as well. My question is - why in the first code I can call the set_name method using the . (meaning mylist[0] is an object) and in the second code I have to use the -> operator (meaning mylist[0] is a pointer to the object)?
T* represents a pointer type, which represents a variable that contains a "reference" (usually a memory address) to some instance of type T. Using a real world comparison, a T* pointer stands to T like a street address stands to a building.
Pointers allow you to refer to some instance owned by some other variable, and you can use a valid, non null instance of T* to read and write on a T. In this, they are similar to another C++ concept, references (written as T&), which allow you to alias variables, but differ significantly from pointers by not being objects in their own regard.
A pointer is, in fact, an object itself, with each pointer variable having its own unique address and being thus storable and referenceable. For instance, you can have pointers to pointers (T**) and references to pointers (T*&), but not pointers to references - pointers exist, while references may not (they are usually implemented as pointers underneath though).
To reflect the this "indirect" nature of pointers, C and C++ provide you with two different operators which allow you to dereference a pointer (* and ->), and to reference a variable (&).
For instance, you may do the following:
struct A { int x; };
// ...
A a {};
A *aptr { &a }; // `&` takes the address of `a` and stores it into the `aptr` variable of type `A*`
aptr->x = 33; // `->` is equivalent here to `(*aptr).x`, a.x is now 33
A a2 {};
A **aptrptr { &aptr }; // pointer to pointer
*aptrptr = &a2; // `aptr` now points to `a2`
operator-> is basically syntactic sugar that avoids you some cumbersome expressions like (*aptr).x.
References, being basically just aliases to something else, do not need any special syntax at all, and are always converted transparently when neeeded:
int x { 33 };
int &xref { x }; // `xref` refers to `x`
xref = 12; // `x` is now 33
int y = xref; // copies `x` into `y`, no special syntax needed
Pointers are also used in the C language to access arrays, which always decay to a pointer as soon as they are referred to in expressions. This is messy and it's one of the reasons std::vector and std::array should always be used in their place when feasible.
int x[33];
x[3] = 44; // equivalent to `*(&x[0] + 3) = 44`
Finally, the "indirect" nature of pointers and references allow C++ to convert a Derived* to a Base*, given that a derived class contains a full instance of its base (it gets more complicated with multiple inheritance though).
Every class that inherits or contains from another class containing virtual methods will include a hidden pointer to a _Virtual Method Table`, a list of pointers to functions which will be used to dispatch the virtual methods to the correct implementation.
PS: in modern C++, you should rarely need raw pointers. The correct approach is to use containers such as std::vector, std::array and std::string, and special pointer-like wrappers called smart pointers (like std::unique_ptr) every time you need a pointer for some reason. These will handle the lifetime of a pointer for you, avoiding memory leaks and vastly simplifying memory handling. For the same reason, the new operator should be mostly considered as being deprecated and should not be used at all (unless in placement new expressions, are potentially dangerous if used improperly).
basically the first case works like this: you have an array of objects. To access the object fields and methods you use . operator.
In the second case you have an array of pointers to an object. Pointer is just a memory address, that points to an object of some type. In your case, this is an array of pointers to class person. By default, these pointers are invalid; you have to set them to the address of some existing object. new creates an object on the heap, and returns you an address of that object. In order to access the value behind the pointer, you have to de-reference it. The syntax is this:
some_type obj;
some_type* ptr = &obj; // get the address of the object
(*ptr).some_method(); // de-reference the pointer and call it
ptr->some_method(); // same

Copying addresses of objects containing an atomic member?

Lets say I have a struct AtomicElement:
struct AtomicElement{
std::atomic<int32_t> a;
};
and I have another class, Object, which contains a reference to one of the above AtomicElement objects:
struct Object{
AtomicElement& ae;
};
Now elsewhere I have a vector of these AtomicElement objects and I would like to update Object::ae to point to different vector elements:
std::vector<AtomicElement> aeVector(AtomicElement());
Object obj;
.
.
//Obtain the address to the new element
AtomicElement& raw_ae = aeVector[i];
.
.
//Change to point to the new element
obj.ae = raw_ae; //Cannot get this part to compile.
What am I doing wrong?
My AtomicElement is only 32 bits, should I just be using by value?
I want to do this in the most efficient way possible, with as little copying as possible.
EDIT:
The 32-bit int is actually representing two 16-bit numbers and the atomicity is so the value is updated.... atomically. I'm wondering if I'd be better off defining a copy constructor as copying 32-bit int would be quicker than pointer dereferencing?
You can't reassign references, but you can use pointers. (Would have commented but don't have the rep.)
However, since an std::atomic is (most likely, but depends on your architecture) useful because of the way it funnels all access through atomic member functions, not because of any extra member data that makes it atomic, copying it around is probably equivalent to copying an int, and it may indeed be faster if you don't need reference semantics, because dereferencing memory is relatively slow. As mentioned in the comments, you'll have to define what it means to copy it to satisfy your needs.
Type & value = reference;is more and less similar to Type * const value = &reference while to set a value you need to do so respectively through value = Type() and *value = Type(). As a fact, you CANNOT change the address of a reference in both ways once defined and it is mandatory to define them at their declaration.
In your case, the issue is that by doing obj.ae = raw_ae; you are not attempting to change the reference but to assign a new value to the current referencee of obj.ae. As std::atomic is declared as a non-copyable class, you got an appropriate compiler error.
If you need to be able to switch to another referencee, you must use a pointer instead.

How does a copy of the data in one data structure to another work in C++?

I have a class that looks like:
class A
{
public:
A();
void MethodThatWillNotBeInOtherStructure();
inline int getData() { return data; }
inline void setData(int data_) { data = data_; }
private:
int data;
}
and a structure like:
struct B
{
public:
inline int getData() { return data; }
inline void setData(int data_) { data = data_; }
private:
int data;
}
How can I copy an instance of A to B without individually setting the fields? I know I can as I have seen code that would take a void* of say A and pass it to a function expecting B and it work. My big question also, is how does this work? I suppose it has something to do with memcpy, but I don't know how the memory layout for the structure and the class will be. For example, how do the functions that are in one but not the other not get in the way of the memcpy? Could someone explain this to me?
Update
Ok, let me explain. I am not saying I would ever do this in reusable code or that I would ever use it period. I still want to know how it works. Does a class have a different memory layout than a structure? How are the methods stored? Where is the data stored?
Thanks!
Copying two unrelated structures in to each other through void * would work properly only if the two structures have the same memory layout. Otherwise the copying fails.
Note that the objects of structure A and B in your above code will have the same memory layout, since there member variables are identical.
Copying through void * works because one is just copying the actual memory occupied by one structure object in to memory occupied by another structure object.
It is basically a bad idea to copy two unrelated structures in this way.
Consider the situation where you have pointers members inside your structure, a memcpy would just cause a shallow copy of the pointer members, And if one of the object finishes its lifetime then eventually, the other object will be left with a dangling pointer member. That would eventually lead to an Undefined behavior(most likely a crash).
How are the methods stored? Where is the data stored?
A normal function(non virtual) will be stored somewhere in the code section of the program. This location is the same for all instances of the class/structure and hence it is not a part of the memory allocation of each object of the class/structure.
In case of a virtual member function, the size of an class/structure does get affected due to presence of virtual functions, each object of the class/structure then has a special pointer called vptr inside each this. Note that this is implementation detail of compilers and compilers may choose to implement it differently.
Knowing the memory layout is quite important when you're using unsafe mechanisms like memcpy to copy the structure. Once it's modified later, you entire logic may screwed up.
Objects of a class doesn't contain the functions. The memory of an object contains only the attributes and the required size for it. On the other hand, functions are executable peice of code which is common across the program and will not influence the structure's memory layout.
I'd suggest you to define operator=, constructors to appropriately casting one object to another.
The additional glitch on memcpy is that, the object may contain virtual pointer if the class has virtual functions. Additional pointer data may also be copied to the destination memory; which is not really good!
You can copy the A to B using memcpy since they have the same member variables. The functions are not part the instances, so they don't matter.
I would recommend against this approach. If either A or B changes, then your copy will fail at run-time. You can make a a constructor of B which takes A, a conversion function, or something. Though it will require a little more code, it will allow for changes to the structures.
Your best bet is probably to implement constructor of struct B that takes a const reference to a struct A. Use that directly or use the assignment operator (which you probably will need to implement for non-trivial cases).
A a;
... (populate a)
B b(a); //If you want to set b to a at instantiation.
b = B(a); //If you want to overwrite an existing instance of struct B with a.
EDIT:
To respond to your edit, it is entirely compiler dependent. The fact that it works at all for a class is reliant on compiler details, since AFAIK it's not supported by the standard. The compiler devs could decide to mess with people by making it work for CLASS but not STRUCT (or vice versa).
That said, I've never seen any difference in any compiler I've used. I would expect them to map memory identically.

Memory structure of a function-only object?

Let's say we have a class that looks like this:
class A
{
public:
int FuncA( int x );
int FuncB( int y );
int a;
int b;
};
Now, I know that objects of this class will be laid out in memory with just the two ints. That is, if I make a vector of instances of class A, there will be two ints for one instance, then followed by two ints for the second instance etc. The objects are POD.
BUT let's say the class looks like this:
class B
{
public:
int FuncA( int x );
int FuncB( int y );
};
What do objects of this class look like in memory? If I fill a vector with instances of B... what's in the vector? I've been told that non-virtual member functions are in the end compiled as free functions somewhere completely unrelated to the instances of the class in which they're declared (virtual function are too, but the objects store a vtable with function pointers). That the access restrictions are merely at the semantic, "human" level. Only the data members of a class (and the vtable etc.) actually make up the memory structure of objects.
So again, what do objects of class B look like in memory? Is it some kind of placeholder value? Something has to be there, I can take the object's address. It has to point to something. Whatever it is, is the compiler allowed to inline/optimize out these objects and treat the method calls as just normal free function calls? If I create a vector of these and call the same method on every object, can the compiler eliminate the vector and replace it with just a bunch of normal calls?
I'm just curious.
All objects in C++ are guaranteed to have a sizeof >= 1 so that each object will have a unique address.
I haven't tried it, but I would guess that in your example, the compiler would allocate but not initialize 1 byte for each function object in the array/vector.
As Ferruccio said, All objects in C++ are guaranteed to have a size of at least 1. Mostly likely, it's 1 byte, but fills out the size of the alignment, but whatever.
However, when used as a base class, it does not need to fill any space, so that:
class A {} a; // a is 1 byte.
class B {} b; // b is 1 byte.
class C { A a; B b;} c; // c is 2 bytes.
class D : public A, B { } d; // d is 1 byte.
class E : public A, B { char ee; } e; // e is only 1 byte
What do objects of this class look like in memory?
It's entirely up to the compiler. An instance of an empty class must have non-zero size, so that distinct objects have distinct addresses (unless it's instantiated as a base class of another class, in which case it can take up no space at all). Typically, it will consist of a single uninitialised byte.
Whatever it is, is the compiler allowed to inline/optimize out these objects and treat the method calls as just normal free function calls?
Yes; the compiler doesn't have to create the object unless you do something like taking its address. Empty function objects are used quite a lot in the Standard Library, so it's important that they don't introduce any unnecessary overhead.
I performed the following experiment:
#include <iostream>
class B
{
public:
int FuncA( int x );
int FuncB( int y );
};
int main()
{
std::cout << sizeof( B ) ;
}
The result was 1 (VC++ 2010)
It seems to me that the class actually requires no memory whatsoever, but that an object cannot be zero sized since that would make no semantic sense if you took its address for example. This is borne out by Ferruccio's answer.s
Everything I say from here on out is implementation dependent - but most implementations will conform.
If the class has any virtual methods, there will be an invisible vtable pointer member. That isn't the case with your example however.
Yes, the compiler will treat a member function call the same as a free function call, again unless it's a virtual function. Even if it is a virtual function, the compiler can bypass the vtable if it knows the concrete type at the time of the call. Each call will still depend on the object, because there's an invisible this parameter with the object's pointer that gets added to the call.
I would think they just look like any objects in C++:
Each instance of the class occupies space. Because objects in C++ must have a size of at least 1 (so they have unique addresses, as Ferruccino said), objects that don't specify any data don't receive special treatment.
Non-virtual functions do not occupy any space at all in a class. Rather, they can be thought of as functions like this:
int B_FuncA(B *this, int x);
int B_FuncB(B *this, int y);
If this class can be used by other .cpp files, I think these will become actual class instances, not regular functions.
If you just want your functions to be free rather than bound to objects, you could either make them static or use a namespace.
I've been told that non-virtual member functions are in the end compiled as free functions somewhere completely unrelated to the instances of the class in which they're declared (virtual function are too, but the objects store a vtable with function pointers). That the access restrictions are merely at the semantic, "human" level. Only the data members of a class (and the vtable etc.) actually make up the memory structure of objects.
Yep, that is usually how it works. It might be worth pointing out the distinction that this isn't specified in the standard, and it's not required -- it just makes sense to implement classes like this in the compiler.
So again, what do objects of class B look like in memory? Is it some kind of placeholder value? Something has to be there, I can take the object's address
Exactly. :)
The C++ standard requires that objects take up at least one byte, for exactly the reason you say. It must have an address, and if I put these objects into an array, I must be able to increment a pointer in order to get "the next" object, so every object must have a unique address and take up at least 1 byte. (Of course, empty objects don't have to take exactly 1 byte. Some compilers may choose to make them 4 bytes, or any other size, for performance reasons)
A sensible compiler won't even make it a placeholder value though. Why bother writing any specific value into this one byte? We can just let it contain whatever garbage it held when the object was created. It'll never be accessed anyway. A single byte is just allocated, and never read or written to.

Managing C++ objects in a buffer, considering the alignment and memory layout assumptions

I am storing objects in a buffer. Now I know that I cannot make assumptions about the memory layout of the object.
If I know the overall size of the object, is it acceptible to create a pointer to this memory and call functions on it?
e.g. say I have the following class:
[int,int,int,int,char,padding*3bytes,unsigned short int*]
1)
if I know this class to be of size 24 and I know the address of where it starts in memory
whilst it is not safe to assume the memory layout is it acceptible to cast this to a pointer and call functions on this object which access these members?
(Does c++ know by some magic the correct position of a member?)
2)
If this is not safe/ok, is there any other way other than using a constructor which takes all of the arguments and pulling each argument out of the buffer one at a time?
Edit: Changed title to make it more appropriate to what I am asking.
You can create a constructor that takes all the members and assigns them, then use placement new.
class Foo
{
int a;int b;int c;int d;char e;unsigned short int*f;
public:
Foo(int A,int B,int C,int D,char E,unsigned short int*F) : a(A), b(B), c(C), d(D), e(E), f(F) {}
};
...
char *buf = new char[sizeof(Foo)]; //pre-allocated buffer
Foo *f = new (buf) Foo(a,b,c,d,e,f);
This has the advantage that even the v-table will be generated correctly. Note, however, if you are using this for serialization, the unsigned short int pointer is not going to point at anything useful when you deserialize it, unless you are very careful to use some sort of method to convert pointers into offsets and then back again.
Individual methods on a this pointer are statically linked and are simply a direct call to the function with this being the first parameter before the explicit parameters.
Member variables are referenced using an offset from the this pointer. If an object is laid out like this:
0: vtable
4: a
8: b
12: c
etc...
a will be accessed by dereferencing this + 4 bytes.
Basically what you are proposing doing is reading in a bunch of (hopefully not random) bytes, casting them to a known object, and then calling a class method on that object. It might actually work, because those bytes are going to end up in the "this" pointer in that class method. But you're taking a real chance on things not being where the compiled code expects it to be. And unlike Java or C#, there is no real "runtime" to catch these sorts of problems, so at best you'll get a core dump, and at worse you'll get corrupted memory.
It sounds like you want a C++ version of Java's serialization/deserialization. There is probably a library out there to do that.
Non-virtual function calls are linked directly just like a C function. The object (this) pointer is passed as the first argument. No knowledge of the object layout is required to call the function.
It sounds like you're not storing the objects themselves in a buffer, but rather the data from which they're comprised.
If this data is in memory in the order the fields are defined within your class (with proper padding for the platform) and your type is a POD, then you can memcpy the data from the buffer to a pointer to your type (or possibly cast it, but beware, there are some platform-specific gotchas with casts to pointers of different types).
If your class is not a POD, then the in-memory layout of fields is not guaranteed, and you shouldn't rely on any observed ordering, as it is allowed to change on each recompile.
You can, however, initialize a non-POD with data from a POD.
As far as the addresses where non-virtual functions are located: they are statically linked at compile time to some location within your code segment that is the same for every instance of your type. Note that there is no "runtime" involved. When you write code like this:
class Foo{
int a;
int b;
public:
void DoSomething(int x);
};
void Foo::DoSomething(int x){a = x * 2; b = x + a;}
int main(){
Foo f;
f.DoSomething(42);
return 0;
}
the compiler generates code that does something like this:
function main:
allocate 8 bytes on stack for object "f"
call default initializer for class "Foo" (does nothing in this case)
push argument value 42 onto stack
push pointer to object "f" onto stack
make call to function Foo_i_DoSomething#4 (actual name is usually more complex)
load return value 0 into accumulator register
return to caller
function Foo_i_DoSomething#4 (located elsewhere in the code segment)
load "x" value from stack (pushed on by caller)
multiply by 2
load "this" pointer from stack (pushed on by caller)
calculate offset of field "a" within a Foo object
add calculated offset to this pointer, loaded in step 3
store product, calculated in step 2, to offset calculated in step 5
load "x" value from stack, again
load "this" pointer from stack, again
calculate offset of field "a" within a Foo object, again
add calculated offset to this pointer, loaded in step 8
load "a" value stored at offset,
add "a" value, loaded int step 12, to "x" value loaded in step 7
load "this" pointer from stack, again
calculate offset of field "b" within a Foo object
add calculated offset to this pointer, loaded in step 14
store sum, calculated in step 13, to offset calculated in step 16
return to caller
In other words, it would be more or less the same code as if you had written this (specifics, such as name of DoSomething function and method of passing this pointer are up to the compiler):
class Foo{
int a;
int b;
friend void Foo_DoSomething(Foo *f, int x);
};
void Foo_DoSomething(Foo *f, int x){
f->a = x * 2;
f->b = x + f->a;
}
int main(){
Foo f;
Foo_DoSomething(&f, 42);
return 0;
}
A object having POD type, in this case, is already created (Whether or not you call new. Allocating the required storage already suffices), and you can access the members of it, including calling a function on that object. But that will only work if you precisely know the required alignment of T, and the size of T (the buffer may not be smaller than it), and the alignment of all the members of T. Even for a pod type, the compiler is allowed to put padding bytes between members, if it wants. For a non-POD types, you can have the same luck if your type has no virtual functions or base classes, no user defined constructor (of course) and that applies to the base and all its non-static members too.
For all other types, all bets are off. You have to read values out first with a POD, and then initialize a non-POD type with that data.
I am storing objects in a buffer. ... If I know the overall size of the object, is it acceptable to create a pointer to this memory and call functions on it?
This is acceptable to the extent that using casts is acceptable:
#include <iostream>
namespace {
class A {
int i;
int j;
public:
int value()
{
return i + j;
}
};
}
int main()
{
char buffer[] = { 1, 2 };
std::cout << reinterpret_cast<A*>(buffer)->value() << '\n';
}
Casting an object to something like raw memory and back again is actually pretty common, especially in the C world. If you're using a class hierarchy, though, it would make more sense to use pointer to member functions.
say I have the following class: ...
if I know this class to be of size 24 and I know the address of where it starts in memory ...
This is where things get difficult. The size of an object includes the size of its data members (and any data members from any base classes) plus any padding plus any function pointers or implementation-dependent information, minus anything saved from certain size optimizations (empty base class optimization). If the resulting number is 0 bytes, then the object is required to take at least one byte in memory. These things are a combination of language issues and common requirements that most CPUs have regarding memory accesses. Trying to get things to work properly can be a real pain.
If you just allocate an object and cast to and from raw memory you can ignore these issues. But if you copy an object's internals to a buffer of some sort, then they rear their head pretty quickly. The code above relies on a few general rules about alignment (i.e., I happen to know that class A will have the same alignment restrictions as ints, and thus the array can be safely cast to an A; but I couldn't necessarily guarantee the same if I were casting parts of the array to A's and parts to other classes with other data members).
Oh, and when copying objects you need to make sure you're properly handling pointers.
You may also be interested in things like Google's Protocol Buffers or Facebook's Thrift.
Yes these issues are difficult. And, yes, some programming languages sweep them under the rug. But there's an awful lot of stuff getting swept under the rug:
In Sun's HotSpot JVM, object storage is aligned to the nearest 64-bit boundary. On top of this, every object has a 2-word header in memory. The JVM's word size is usually the platform's native pointer size. (An object consisting of only a 32-bit int and a 64-bit double -- 96 bits of data -- will require) two words for the object header, one word for the int, two words for the double. That's 5 words: 160 bits. Because of the alignment, this object will occupy 192 bits of memory.
This is because Sun is relying on a relatively simple tactic for memory alignment issues (on an imaginary processor, a char may be allowed to exist at any memory location, an int at any location that is divisible by 4, and a double may need to be allocated only on memory locations that are divisible by 32 -- but the most restrictive alignment requirement also satisfies every other alignment requirement, so Sun is aligning everything according to the most restrictive location).
Another tactic for memory alignment can reclaim some of that space.
If the class contains no virtual functions (and therefore class instances have no vptr), and if you make correct assumptions about the way in which the class' member data is laid out in memory, then doing what you're suggesting might work (but might not be portable).
Yes, another way (more idiomatic but not much safer ... you still need to know how the class lays out its data) would be to use the so-called "placement operator new" and a default constructor.
That depends upon what you mean by "safe". Any time you cast a memory address into a point in this way you are bypassing the type safety features provided by the compiler, and taking the responsibility to yourself. If, as Chris implies, you make an incorrect assumption about the memory layout, or compiler implementation details, then you will get unexpected results and loose portability.
Since you are concerned about the "safety" of this programming style it is likely worth your while to investigate portable and type-safe methods such as pre-existing libraries, or writing a constructor or assignment operator for the purpose.