views:

209

answers:

9

Hello. Is there a standard in storing a C++ objects in memory? I wish to set a char* pointer to a certain address in memory, so that I can read certain objects' variables directly from the memory byte by byte. When I am using Dev C++, the variables are stored one by one right in the memory address of an object in the order that they were defined. Now, can it be different while using a different compiler (like the variables being in a different order, or somewhere else)? Thank you in advance. :-)

+3  A: 

The variables can't be in a different order, as far as I know. However, there may be varying amounts of padding between members. Also I think all bets are off with virtual classes and different implementations of user-defined types (such as std::string) may be completely different between libraries (or even build options).

It seems like a very suspicious thing to do. What do you need it for: to access private members?

UncleBens
The variables can be in a different order if they have access specifiers in between them. For example, `public: int x; int y;` must be in order. `public: int x; public: int y;` need not be (but in fact almost certainly will). 9.2/12.
Steve Jessop
+3  A: 

I believe that the in-memory layout of objects is implementation defined - not the ordering, necessarily, but the amount of space. In particular, you will probably run into issues with byte-alignment and so-forth, especially across platforms.

Can you give us some details of what you're trying to do?

jwismar
I am trying to read the variables on the byte level, send them over a tcp/ip socket and put write them to an object-representative. Is there an easier way of doing it? (I wish my algorithm to be universal, no matter what variables the object contains)
Neo_b
A: 

Keep in mind when working with multi-dimensional arrays that they are stored in Row Major Order.

Erik Ahlswede
A: 

The order of the variables should never change, but as others have said, the byte packing will vary. Another thing to consider is the endianness of the platform.

To get around the byte alignment/packing problem, most compilers offer some way to guide the process. In gcc you could use __attribute__((__packed__)) and in msvc #pragma pack.

My answer might be more relevant for traditional structs than complex classes.
+1  A: 

Implementations are free to do anything they want :P. However since C++ has to appeal to certain styles of programming, you will find a deterministic way of accessing your fields for your specific compiler/platform/cpu architecture.

If your byte ordering is varied on a different compiler, my first assumption would be byte packing issues. If you need the class to have a certain specific byte ordering first look up "#pragma pack" directives for your compiler... you can change the packing order into something less optimal but deterministic. Please note this piece of advice generally applies to POD data types.

Hassan Syed
A: 

I've worked with something that did this professionally, and as far as I could tell, it worked very specifically because it was decoding something another tool encoded, so we always knew exactly how it worked.

We did also use structs that we pointed at a memory address, then read out data via the struct's variables, but the structs notably included packing and we were on an embedded platform.

Basically, you can do this, so long as you know -exactly- how everything is constructed on a byte-by-byte level. (You might be able to get away with knowing when it's constructed the same way, which could save some time and learning)

Narfanator
+1  A: 

The C++ compiler is not allowed to reorder variables within a visibility block (public, protected, etc). But it is allowed to reorder variables in separate visibility blocks. For example:

struct A {
    int a;
    short b;
    char c;
};

struct B {
    int a;
public:
    short b;
protected:
    char c;
};

In the above, the variables in A will always be laid out in the order a, b, c. The variables in B might be laid out in another order if the compiler chose. And, of course, there are alignment and packing requirements so there might be "spaces" between some of the variables if needed.

Peter
A: 

It sounds like you want to marshall objects between machines over a TCP/IP connection. You can probably get away with this if the code was compiled with the same compiler on each end, otherwise, I'm not so sure. Keep in mind that if the platforms can be different, then you might need to take into account different processor endians!

Gordon
In thinking about this more... I actually did something like this years ago. I recall defining a base class CRemoteable and then automatically sending the contents of the class (addressed through the 'this' pointer) to remote machines. It worked fine, but all machines were running the same OS and the same program.
Gordon
A: 

Sounds like what you real want to ask is how to serialize your objects

jk