How is an object stored in memory?
class abc
{
public:
int a;
long double b;
vector<string> c;
double x;
};
Suppose that I have a vector of the abc object above. I would like to sort it by the different data. Rather than writing a different less than function for each variable, I'm trying to develope a generic version that is based off of offset.
class GenericLessThen
{
public:
GenericLessThen(void * _val, void * _base)
{
offset = (char *)_val - (char *)_base;
};
bool operator()(Case & itemA, Case & itemB )
{
return false;
}
private:
int offset;
};
couple of questions:
1) what is the order of memeber data that gets stored in memory? by the line order?
2) will the offset for each member data always be the same between objects?
3) in the case of a vector, since each abc object might have a different size
vector c, what is stored in the abc object?
if it is the address to the vector head, does that mean each abc object will always have the same size in memory? (not counting the memory used by the vector)
or is the entire vector stored "inline" within the abc object? so in this case, the offset for each member data after the vector will be different depending on how big the vector is?
4) Assuming that the offset is the same, how would I determine the type of data that is at the offsect? I'm using void * to do the arithmetic but found that I've no efficient way of casting to the right data type when I actually compare.
Thanks!
[1631 byte] By [
rssmps] at [2007-11-11 8:47:33]

# 1 Re: How is an object stored in memory?
1) what is the order of memeber data that gets stored in memory? by the line order?
-The compiler is free to do as it pleases here.
2) will the offset for each member data always be the same between objects?
- Yes, as far as I know this will be the case.
3) in the case of a vector, since each abc object might have a different size
vector c, what is stored in the abc object?
if it is the address to the vector head, does that mean each abc object will always have the same size in memory? (not counting the memory used by the vector)
r is the entire vector stored "inline" within the abc object? so in this case, the offset for each member data after the vector will be different depending on how big the vector is?
I don't fully understand you. However this might help: a vector is a template class, so if the template type changes (vector<int> vs vector <someclass>) the size and offsets of the vector will not be similar (they are really two different classes!, think of them as class vector1 and class vector2)
4) Assuming that the offset is the same, how would I determine the type of data that is at the offsect? I'm using void * to do the arithmetic but found that I've no efficient way of casting to the right data type when I actually compare.
I think you are getting into trouble here. However, look at run time type info (rtti) and see if that is what you need.
Thanks!
jonnin at 2007-11-11 21:01:02 >

# 2 Re: How is an object stored in memory?
I don't fully understand you. However this might help: a vector is a template class, so if the template type changes (vector<int> vs vector <someclass>) the size and offsets of the vector will not be similar (they are really two different classes!, think of them as class vector1 and class vector2)
Let me ******** my question...when I define vector<int> c;
what is stored in the oject? is it the address of the start of the vector?
so the variable immediately after the vector is always 4bytes away from the variable preceding the vector?
I think you are getting into trouble here. However, look at run time type info (rtti) and see if that is what you need.
I'm thinking of getting around this issue by having a generic function for each type of variable (int, double, etc.) This way, I know exactly what I'm casting back to.
I looked at RTTI but that seems to be more towards the virtual/inheritance.
2) will the offset for each member data always be the same between objects?
- Yes, as far as I know this will be the case.
in my sample class above, there no string variables.
what if a data member is a string?
if object A had 10 chars, and B had 50 chars. Does that mean the next variable in B will have an offset that is 40 more than the same variable in obj
A?
is using memory offset dangerous?
rssmps at 2007-11-11 21:02:02 >

# 3 Re: How is an object stored in memory?
Let me ******** my question...when I define vector<int> c;
what is stored in the oject? is it the address of the start of the vector?
so the variable immediately after the vector is always 4bytes away from the variable preceding the vector?
The object has the data and functions associated with the vector class (created from the template). This is not a pointer, its a class variable. If you took the raw address of the variable, at some offset would be the "array" or pointer to the actual data, but the offset will vary from compiler to compiler and (possibly) across different vector types. If you are looking for the raw data, however, you can get to that via member functions / data members; or simply use vectorVar[x] notation like an array. The bottom line is that the vector class has a LOT of stuff in it, its not just a simple class wrapper around a pointer or anything remotely like that.
jonnin at 2007-11-11 21:03:02 >

# 4 Re: How is an object stored in memory?
class loadCaseGenericLTLongDouble
{
public:
loadCaseGenericLTLongDouble(long double * _val, LoadCase * _base)
{
offset = (char *)_val - (char *)_base;
};
bool operator()(LoadCase & itemA, LoadCase & itemB )
{
void * A = &itemA;
void * B = &itemB;
//**********************
A = (char*)A + offset;
B = (char*)B + offset;
//**********************
long double Aprime = *((long double *)A);
long double Bprime = *((long double *)B);
if(Aprime<Bprime)
return true;
else
return false;
}
private:
int offset;
};
yeah, I forgot to account for all the other stuff in a vector object.
What I'm getting at is the two lines between the rows of stars, is this a safe way to use offset? as long as the same data between objects have the same offset, I should be ok.
I just didn't know if variable length ojects (string, vectors, etc) will affect the offset of other member data in any way.
rssmps at 2007-11-11 21:04:01 >

# 5 Re: How is an object stored in memory?
I just didn't know if variable length ojects (string, vectors, etc) will affect the offset of other member data in any way
It *should* not, as those are actually pointers. so the memory layout would be something like
member data
member data
member data
-- *** pointer to dynamic memory for the data you seek, same place, same offset
method
method
more stuff
So it *should* be safe and all, but is risky, less than portable (might work on one compiler and not another) and not exactly the "right way to go about it" unless you have a very compelling reason (noticable performance increase, only way to link in some legacy code, or the like).
jonnin at 2007-11-11 21:05:07 >

# 6 Re: How is an object stored in memory?
OK, I joined you a bit late, but I want to clairfy a few things:
First of all, in your original post, the compiler *is* obliged to lay members in the resective order of their declarations. That is &a, &b &c etc. must have ascending memory addresses. The compiler can't shuffle members here, say moving b before a, so it's safe to assume that each member has a higher address as long as the data members are all declared without an intervening access specifier. That is, if you do something like this:
private:
int a;
public:
int b;
In this case, the compiler is free to assign arbitrary memory addresses for the members.
As for yoru second question: the offset between members may be higher than you expect because the compiler is allowed to insert padding bytes. That is, there could be "empty" bytes between each member. This is why you shouldn't assume that &a + sizeof (a) == &b.
Thridly, the c object, i.e., the vector is represented as an instance of the vector class template, which is NOT the same as storing an array of elements. The vector's elements are NOT placed in this section, and in fact, they are not stored inside abc at all. The strings that make the elements of the vector are stored on the heap, in a completely different adddress space. The only relic of these objects is a pointer stored within c, which points to the array of strings. That pointer is transient, which means that you can't calculate it at compile time, nor can you store its value in a file and read it when you run the application once more.
Danny at 2007-11-11 21:06:11 >

# 7 Re: How is an object stored in memory?
I just didn't know if variable length ojects (string, vectors, etc) will affect the offset of other member data in any way
It *should* not, as those are actually pointers. so the memory layout would be something like
member data
member data
member data
-- *** pointer to dynamic memory for the data you seek, same place, same offset
method
method
more stuff
So it *should* be safe and all, but is risky, less than portable (might work on one compiler and not another) and not exactly the "right way to go about it" unless you have a very compelling reason (noticable performance increase, only way to link in some legacy code, or the like).
The number of elemenets of a container, say vector or string, has absolutely no signifcance here. The container object's size (i.e., what you get from a sizeof(vector<X>) expression) is fixed, and determined at compile time. By contrast, the number of elements is determined at runtime and may change. It's always detached from the memory of the container itself. That is, the elenents of a string vector etc. are accessed by a pointer, so whether a string object has 10 chars or 10 million chars doesn't really matter -- the string object itself will always have the same binary layout.
Danny at 2007-11-11 21:07:11 >

# 8 Re: How is an object stored in memory?
One more thing: I think I lost your at some point, so you can you please rephrase your question and focus on the offset issue itself? More specifically, what are _val and _base exactly in the following function?
loadCaseGenericLTLongDouble(long double * _val, LoadCase * _base)
Are they members of the same object?
Danny at 2007-11-11 21:08:08 >

# 9 Re: How is an object stored in memory?
One more thing: I think I lost your at some point, so you can you please rephrase your question and focus on the offset issue itself? More specifically, what are _val and _base exactly in the following function?
loadCaseGenericLTLongDouble(long double * _val, LoadCase * _base)
Are they members of the same object?
Yes, members of a same object.
where _val is the location of the value I'm interested in within the ojbect, and _base is the start of the object.
By calculating the offset, I can know which value within the LoadCase object i'm interested in comparing.
when you talked about padding, is the padding the same for every object or would each object have a different padding?
Here's the situation:
I've got a vector of LoadCase objects. Each LoadCase consists of many data members (nested structs, strings, vectors, etc...).
So depending on what the user wants, I want to be able to sort the vector of LoadCase objects based on a certain field of data in the load case objects.
I've been brute forcing it by writing a specific lessThan fuction for each value in the LoadCase object. This is fine for a few values but if I want to allow sorting based on every value, I'm looking at over 50 specific lessThan functions.
Instead, I thought of using offsets.
sort(sf1.loadCases.begin(),
sf1.loadCases.end(),
loadCaseGenericLTLongDouble
(
&sf1.loadCases[0].structA.structB.valueX,
&sf1.loadCases[0]
)
);
class loadCaseGenericLTLongDouble
{
public:
loadCaseGenericLTLongDouble(long double * _val, LoadCase * _base)
{
offset = (char *)_val - (char *)_base;
};
bool operator()(LoadCase & itemA, LoadCase & itemB )
{
void * A = &itemA;
void * B = &itemB;
//**********************
A = (char*)A + offset;
B = (char*)B + offset;
//**********************
long double Aprime = *((long double *)A);
long double Bprime = *((long double *)B);
if(Aprime<Bprime)
return true;
else
return false;
}
private:
int offset;
};
does this make sense?
rssmps at 2007-11-11 21:09:06 >

# 10 Re: How is an object stored in memory?
If you need to calculate the relative position of a member within an object, you should use pointers to data members (run a search on dev-archive's main page and you will find my 20 C++ Tips Of All Times, which discuss this topic). As for padding, it varies. It depends on the size of each member. So if you have a small member that occupies 1 byte, there can be 1, 3, or 7 bytes after that member and before the next one. So you can't assume that every padding byte sequence is the same.
Danny at 2007-11-11 21:10:08 >

# 11 Re: How is an object stored in memory?
I had already looked at pointers to data members. I did not see how that would help in my goal of writing a generic less than function. what would go in this function?
bool operator()(LoadCase & itemA, LoadCase & itemB ){}
in my code, all the nubmers are long double so I guess padding, if any should be the same. So far, I've sorted based on six different values withing the object and it seems to be working fine.
If using offset is not the right/safe way, how would one write a predicate that allows flexibility? a series of if/then, switch, flag seems inefficient.
rssmps at 2007-11-11 21:11:17 >

# 12 Re: How is an object stored in memory?
I really think you should look into a pointer to data member solution rather than muck around with void * and low level offset calculations. Please remember that pointers to members apply to two categories: the more common pointers to member functions, and the less common pointers to data members. This is almost an ideal solution to your problem since your class has data members of only one type. Also, I don't think it's a good idea letting functions poke into the internals of an object. This is clearly the kind of operations you want to encapulate in a member function of the class itslef. In short, what you need is a member function that accepts an enumeration which tells which data members should be compared, then assign the relevant pointers to data members to the relevant addresses of those members and perform the comparison. The comparison operation itself needn't be a member function.
Danny at 2007-11-11 21:12:17 >

# 13 Re: How is an object stored in memory?
Ok, I'm giving pointer to member data a try.
However I'm running into problems with nested struct data.
my class has the following nested structs.
class someobj{
struct Load
{
long double LV,LS,LA,PM,YM,RM;
}
struct partXDATA{
Load compTotal_PwrOn;
Load compTotal_PwrOff;
long double dragExternal,skinFriction;
} partX;
struct parZDATA
{
Load PwrOnAirload_LRP;
Load PwrOnAirload_WLE;
Load PwrOnInertia_LRP;
Load PwrOnTotal_LRP;
} partZ;
}
and here's my comparison
class genericLTLongDouble
{
public:
genericLTLongDouble(long double LoadCase::*_val)
{
this->pmld = _val;
};
private:
long double LoadCase::*pmld;
};
http://www.informit.com/guides/content.asp?g=cplusplus&seqNum=142&rl=1
from the examples, you have:
int A::*pmi = &A::num;
I tried &someobj:: partX.compTotal_PwrOn.LA but it didn't like anything beyone partX.
does this not work for more then one level of variables?
rssmps at 2007-11-11 21:13:18 >

# 14 Re: How is an object stored in memory?
I haven't really tried such complex class definitions before, especially when pointers to data members are involved (the main reason why they are so rarely used, as opposed to pointers to member functions, is that they violate encapsulation). However, pointers to members point to the immediate members of their class, not deeply embedded ones. You have several options then:
1) use nested pointed to data meber declarations. Frankly, I doubt that there's more a handful of human being who can read and understand such code, so I wouldn't really go for it.
2) Simplify the class declaration. It really seems as if you're trying to create what is known as a God Class, a class which does too much, knows too much, and actually functions as a full blow application. For starters, you may simplify the internal data structures, leveraging them from dumb data structs to full blow classes, and then inherit from them or use them as embedded objects.
3)You seem to be enamored with the notion of offset calculations (seriously, do you really need to be able to sort these objects according to every possible data member? I think I counted about 40 different variables of type long double inside this class!) so you want to look into the offsetof macro. A word of caution: this macro works only for POD types. If your class virtual member functions, a virtual destructor, or base classes, the results of using offsetoff are undefined. Here as well, you need a flat data layout, without nesting types.
Danny at 2007-11-11 21:14:19 >

# 15 Re: How is an object stored in memory?
I would certainly use function pointers. Below is just an example how you can use class member function pointers to choose the right member method. The code will return the Example object with a minimum value of b and than c. This can be enhanced and modified to hopefully suite your needs.
enum whichone {ACMP, BCMP, CCMP }
class Example;
int (Example::*fptr)();
List* ExamplesList ;
Class Example {
private:
int a;
int b;
int c;
public:
Example(int, int, int);
int GetaVal() { return a;}
int GetbVal() { return b;}
int GetcVal() { return c;}
};
Example::Example(int aa, int ab, int ac)
{
a = aa;
b = ab;
c = ac;
ExamplesList->Add(this); //add this object to a list
}
void main()
{
Example* pnewExampleObject;
ExamplesList = new List();
int i;
//let'create 10 Example objects
for ( i=0; i < 10; ++i)
pnewExampleObject = new Example(i, i+1, i+2);
//now find the Example object with a minimum value of b
whichone val = BCMP;
pnewExampleObject = GetExampleobjectByMinVal(val);
//now find the Example object with a minimum value of c
val = CCMP;
pnewExampleObject = GetExampleobjectByMinVal(val); //get Example object with minimum c
//delete Example objects
for (int i=0; i < 10; ++i)
delete (Example*)ExamplesList->Items[i];
delete ExamplesList; //delete the list object
}
void InitMemberPointers(whichone val)
{
switch (val) {
case ACMP:
fptr = &Example::GetaVal;
break;
case BCMP:
fptr = &Example::GetbVal;
break;
case CCMP:
fptr = &Example::GetcVal;
break;
}
}
Example* GetExampleobjectByMinVal(whichone val)
{
Example* ex;
int index = 0;
int minval;
ex = (Example*)ExamplesList->Items[0];
InitMemberPointers(val);
minval = (ex->*fptr)(); //call member function through a member pointer
for (int i=1; i<10; ++i) {
ex = (Example*)ExamplesList->Items[i];
if ((ex->*fptr)() < minval) {
minval = (ex->*fptr)();
index = i;
}
}
return (Example*)ExamplesList->Items[index];
}
Hope some of this will hepl you
Ivan** at 2007-11-11 21:15:11 >

# 16 Re: How is an object stored in memory?
It's a nice idea but it looks like over engineering to me. Let's remember what the origina problem was: comparing an arbitrary long double value. Because the comparison will always compare two long double variables, it's trivial -- you don't need any special code for the comparison itself. The real problem: how to access the specific long double member of an object. As a rule, when a class has something like 40 data members, it's a design gaffe so one needs to go back to the drawing board. However, ignoring this issue for a moement, a much simple solution would be using an array of long double, where each array element has a matching enumerator that tells what its role is:
arr[ENUM_LCM]=0.0;
arr[ENM_VP]=1.0
swtich (enum_load)
case ENUM_LCM:
compare (myobj.getarr(ENUM_LCM), otherobject.getarr(ENUM_LCM));
break;
This is a real object oriented solution -- instead of poking into data members that are supposed to be private anyway, you use an accessor (i.e., getter) function to access the desired member *without* worrying about implmentation details, i.e., are the data members stored as a one big array? a collection of structs etc.
Danny at 2007-11-11 21:16:21 >

# 17 Re: How is an object stored in memory?
Hi
I' not saying that my approach (attempt) is the best. I just think it's worth looking into. Also private members are accessed through the class member methods and not via pointers so encapsulation is preserved.
Ivan** at 2007-11-11 21:17:19 >

# 18 Re: How is an object stored in memory?
Ivan, I wasn't criticising your solution. My criticism was aimed at the idea of having public data members and letting an external function poke into the internals of an object by brute force offset calculations.
Danny at 2007-11-11 21:18:18 >
