tags:

views:

731

answers:

8

For example, say I have a class Temp:

class Temp
{
public:
int function1(int foo) { return 1; }
void function2(int bar) { foobar = bar; }

private:
int foobar;
};

When I create an object of class Temp, how would I calculate how much space it needs, and how is it represented in memory (e.g.| 4 bytes for foobar| 8 bytes for function1 | etc | )

+4  A: 
sizeof(Temp)

will give you the size. Most likely, it is 4 bytes (given a whole lot of assumptions) and that is only for the int. The functions do not take up any room on a per object basis, they are compiled once, and linked by the compiler each time they are used.

It's impossible to say exactly what the object layout is, however, the standard doesn't define the binary representation for objects.

There are a few things to be aware of with binary representations, like they aren't necessarily the sum of the bytes of the data members, due to things like structure padding

Todd Gardner
and also due to things like virtual table pointers.
Here Be Wolves
@harshath.jr: yea but there are no virtual functions in the class shown, so there is no virtual table
newacct
A: 

This may help.

Additionally, class functions are represented just like any other function. The only magic that C++ does to the function is to mangle the function names to uniquely identify a specific function with a specific set of parameters inside a specific class.

sybreon
+2  A: 

Member functions dont account for the size of the objects of a particular class. The size of the object depends only on the member variables. In case of classes that contain virtual functions, the VPTR gets added to the object layout. So the size of the objects is basically size of the member variables + the size of the VPTRs. Sometimes this may not be true as Compilers try to locate member variables at the DWORD boundary.

Canopus
A: 

Here's an excellent book on the subject.

Nikolai N Fetissov
+16  A: 

To a first order approximation, the size of an object is the sum of the sizes of its constituent data members. You can be sure it will never be smaller than this.

More precisely, the compiler is entitled to insert padding space between data members to ensure that each data member meets the alignment requirements of the platform. Some platforms are very strict about alignment, while others (x86) are more forgiving, but will perform significantly better with proper alignment. So, even the compiler optimization setting can affect the object size.

Inheritance and virtual functions add an additional complication. As others have said, the member functions of your class themselves do not take up "per object" space, but the existence of virtual functions in that class's interface generally implies the existence of a virtual table, essentially a lookup table of function pointers used to dynamically resolve the proper function implementation to call at runtime. The virtual table (vtbl) is accessed generally via a pointer stored in each object.

Derived class objects also include all data members of their base classes.

Finally, access specifiers (public, private, protected) grant the compiler certain leeway with packing of data members.

The short answer is that sizeof(myObj) or sizeof(MyClass) will always tell you the proper size of an object, but its result is not always easy to predict.

Drew Hall
+5  A: 

If you want detailed information about how objects are represented in memory at run-time, the ABI (Application Binary Interface) specification is the place to look. You'll need to look determine which ABI your compiler implements; for example, GCC versions 3.2 and above implement the Itanium C++ ABI.

Paul Morie
+3  A: 

Methods belong to the class, not any particular instantiated object.

Unless there are virtual methods, the size of an object is the sum of the size of its non-static members, plus optional padding between the members for alignment. The members will probably be laid out sequentially in memory, but the spec doesn't guarantee ordering between sections with different access specifications, nor ordering relative to the layout of superclasses.

With virtual methods present, there may be additional space taken for vtable and other RTTI information.

On most platforms, executable code goes in the read-only .text (or similarly named) section of the executable or library, and is never copied anywhere. When class Temp has a method public: int function1(int), the Temp metadata may have a pointer to a _ZN4Temp9function1Ei (mangled name may be different depending on compiler) function for the actual implementation, but certainly it would never contain the executable code embedded.

ephemient
+1  A: 

If you want to examine the layout of a particular structure, the offsetof(s,member) macro may also be of use. It tells you how far from the base address of a structure a particular member lives:

struct foo {
  char *a;
  int b;
};

// Print placement of foo's members
void printFoo() {
  printf("foo->a is %zu bytes into a foo\n", offsetof(struct foo, a));
  printf("foo->b is %zu bytes into a foo\n", offsetof(struct foo, b));
}

int main() {
  printFoo();
  return 0;
}

Would print on a typical 32-bit machine:

foo->a is 0 bytes into a foo
foo->b is 4 bytes into a foo

Whereas on a typical 64 bit machine, it would print

foo->a is 0 bytes into a foo
foo->b is 8 bytes into a foo
Novelocrat