Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does C++ store functions and objects in memory? [duplicate]

Lets say we have a class

class A
{
    int x;
public:
    void sayHi()
    {
        cout<<"Hi";
    }
};

int main()
{
    A *a=NULL;
    a->sayHi();
}

The above code will compile on Turbo C (where I tested) and print Hi as output.

I was expecting crash because a is NULL. More over if I make sayHi() function virtual, it says

Abnormal temination(Segmentation fault in gcc) 

I know a lot of it is implementation dependent but if anybody could throw some light on any implementation or just give an overview it would be really nice.

like image 716
user1709663 Avatar asked Sep 30 '12 11:09

user1709663


People also ask

How is a function stored in memory C?

Each time a function is called, the address of where to return to and certain information about the caller's environment, such as some of the machine registers, are saved on the stack. The newly called function then allocates room on the stack for its automatic variables. This is how recursive functions in C can work.

How does memory store function?

This is because in machine code, a function is referenced by its location in RAM, not its name. The compiler-output object file may have a func entry in its symbol table referring to this block of machine code, but the symbol table is read by software, not something the CPU hardware can decode and run directly.

Can we copy a function in C?

In the C Programming Language, the memcpy function copies n characters from the object pointed to by s2 into the object pointed to by s1. It returns a pointer to the destination. The memcpy function may not work if the objects overlap.


2 Answers

As a generalisation, the layout of a object instantiated from a class with no super classes and virtual functions is as follows:

* - v_ptr  ---> *  pTypeInfo
|               |- pVirtualFuncA
|               |- pVirtualFuncB
|- MemberVariableA
|- MemberVariableB

v_ptr is a pointer to the v-table - which contains addresses of virtual functions and RTTI data for the object. Classes without virtual functions don't have v-tables.

In your example above, class A has no virtual methods and thus no v-table. This means the implementation of sayHi() to call can be determined at compile time and is invariant.

The compiler generates code that sets the implicit this pointer to a and then jumps to the beginning of sayHi(). Since the implementation has no need for the object's contents, the fact that it works when the pointer is NULL is a happy coincidence.

If you were to make sayHi() virtual, the compiler cannot determine the implementation to call at compiler time, so instead generates code that looks up the address of the function in the v-table and calls it. In your example where a is NULL, the compiler reads the contents of address 0, causing the abort.

like image 68
marko Avatar answered Oct 12 '22 14:10

marko


In C++, the methods of a class are not stored inside the instances of that class. They're simply some "special" functions that transparently accept the this pointer in addition to the arguments specified by the programmer.

In your case, the sayHi() method does not reference any of the class fields, therefore, the this pointer (which is NULL) is never followed.

Make no mistake, though, this is still undefined behavior. Your program may choose to send nasty emails to your contact list when you invoke this. In this particular instance, it does the worst thing, and appears to work.

The virtual method case has been added since I answered the question, but I won't refine my answer, since it's included by others' answers.

like image 32
enobayram Avatar answered Oct 12 '22 14:10

enobayram