Friday, October 23, 2009
A. Both malloc and new has been used for dynamic memory allocation. Followings are the differences:
1. You will have to typecast the return value of malloc, because malloc returns (void*), but new doesn't require any typecasting.
2. malloc is a C function whereas new is a C++ operator.
3. malloc allocate the amount of memory you ask and return it. But new allocate memory as well as it also call the constructor for which memory has been allocated.
4. On failure malloc return null pointer, but new never returns a null pointer, instead it throws an exception.
Q. What is the difference between delete and delete[]?
A. delete is used to destroy a single object. It will call the destructor of the object and free the memory.
delete[] is used to free the memory which was allocated using new []. delete [] will call the destructor for each object in array and free the memory.
Q. What are the advantages and disadvantages of using #define?
A. It takes up the least memory. Constants defined in this manner are simply placed directly into your source code, with no variable space allocated in memory.
When you use the preprocessor to create constants, you place control of those constants outside the scope of the compiler.
Suppose, #define PI 3.14159
No type checking is performed on the name PI and you can’t take the address of PI (so you can’t pass a pointer or a reference to PI).
PI lasts from the point it is defined to the end of the file;
The preprocessor doesn’t recognize scoping.
The preprocessor has no permission to access class member data. This means preprocessor
macros cannot be used as class member functions.
Q. Explain the Inline Function
A. C++ implements the macro as inline function, which is a true function in every sense. Any behavior you expect from an ordinary function, you get from an inline function. The only difference is that an inline function is expanded in place, like a preprocessor macro, so the
overhead of the function call is eliminated.
Any function defined within a class body is automatically inline, but you can also make a non-class function inline by preceding it with the inline keyword.
you must include the function body with the declaration, otherwise the compiler will treat it as an ordinary function declaration. Thus,
inline int plusOne(int x);
has no effect at all other than declaring the function (which may or may not get an inline definition sometime later). The successful approach provides the function body:inline int plusOne(int x) { return ++x; }
You’ll almost always want to put inline definitions in a header file. When the compiler sees such a definition, it puts the function type (the signature combined with the return value) and the function body in its symbol table. When you use the function, the compiler checks to ensure the call is correct and the return value is being used correctly, and then substitutes the function body for the function call, thus eliminating the overhead.
The inline code does occupy space, but if the function is small, this can actually take less space than the code generated to do an ordinary function call (pushing arguments on the stack and doing the CALL).
Any function you define inside a class definition is automatically an inline.
Inlines & the compiler
To understand when inlining is effective, it’s helpful to know what the compiler does when it encounters an inline. As with any function, the compiler holds the function type (that is, the function prototype including the name and argument types, in combination with the function return value) in its symbol table. In addition, when the compiler sees that the inline’s function type and the function body parses without error, the code for the function body is also brought into the symbol table. Whether the code is stored in source form, compiled assembly instructions, or some other representation is up to the compiler.
When you make a call to an inline function, the compiler first ensures that the call can be correctly made. That is, all the argument types must either be the exact types in the function’s argument list, or the compiler must be able to make a type conversion to the proper types and the return value must be the correct type (or convertible to the correct type) in the destination expression. This, of course, is exactly what the compiler does for any function and is
markedly different from what the preprocessor does because the preprocessor cannot check types or make conversions.
If all the function type information fits the context of the call, then the inline code is substituted directly for the function call, eliminating the call overhead and allowing for further
optimizations by the compiler. Also, if the inline is a member function, the address of the object (this) is put in the appropriate place(s), which of course is another action the preprocessor is
unable to perform.
Limitation:
1. The compiler cannot perform inlining if the function is too complicated. This depends upon the particular compiler, but at the point most compilers give up, the inline probably wouldn’t gain
you any efficiency.
2. The compiler also cannot perform inlining if the address of the function is taken implicitly or explicitly. If the compiler must produce an address, then it will allocate storage for the function
code and use the resulting address. However, where an address is not required, the compiler will probably still inline the code.
Q. What are the advantages and disadvantages of using inline and const?
A.
Inline:
An inline function is expanded in place, like a preprocessor macro, so the overhead of the function call is eliminated.
you must include the function body with the declaration, otherwise the compiler will treat it as an ordinary function declaration.
Const:
The modifier const tells the compiler that a name represents a constant.
Named constant that is just like a variable, except that its value cannot be changed.
you can take the address of a const.
A const has a scope, just like a regular variable.
you can make it a local const inside a function and be sure that the name will not affect the rest of the program.
Q. What is the difference between a pointer and reference?
A.
1. A reference (&) is like a constant pointer that is automatically dereferenced.
2. A reference must be initialized when it is created. (Pointers can be initialized at any time.)
2. Once a reference is initialized to an object, it cannot be changed to refer to another object. (Pointers can be pointed to another object at any time.)
3. You cannot have NULL references. You must always be able to assume that a reference is connected to a legitimate piece of storage.
The fact that there is no such thing as a null reference implies that it can be more efficient to use references than to use pointers. That's because there's no need to test the validity of a reference before using it.
Q. When would you use a pointer? a reference?
A.
Use Pointer: whenever you need to take into account the possibility that there's nothing to
refer to (in which case you can set the pointer to null) or whenever you need to be able to refer to different things at different times (in which case you can change where the pointer points).
Use Reference: whenever you know there will always be an object to refer to and you also know that once you're referring to that object, you'll never want to refer to anything else.
Q. What does it mean to take the address of a reference?
A. Taking the address of a reference, does give you the address of the object referred to.
Q. What does it mean to declare a function or variable as static?
Q. What is the order of initialization for data?
Q. What is name mangling/name decoration?
Q. What kind of problems does name mangling cause?
Q. How do you work around them?
Q. What are the differences between a struct and a class in C++?
Q. What is a constructor initialize list?
Q. What is conversion constructor?
Q. What does mean by destructor as static?
Q. What do you understand by "resource acquisition is initialization" ?
Q. What is difference between operator new and the new operator?
Q. What is placement new?
Q. What happens if an exception is throws from an object's constructor?
Q. What happens if an exception is throws from an object's destructor?
Q. When would you choose to return an error code rather than throw an exception?
Q. What is partial specialization or template specialization?
Q. How can you force instantiation of a template?
Q. What is smart pointer?
Q. What is wrong with this statement?
std::auto_ptr ptr(new char[10]);
Q. It is possible to build a C++ compiler on top of a C compiler. How would you do this?
Wednesday, October 7, 2009
Q. While creation of object, constructor of base class calls first and after that constructor of derived class. But while deletion of object, destructor of derived class calls first then destructor of base class, why?
A: At the time of creation of object, memory is allocated in the stack. First memory has been created for base class then derived class.
As we know, stack is having "LIFO" (Last in First out) behaviour. Here derived class entered at the last in the stack, while creating object, so while deleting, it will be deleted first. And that is the reason, destructor of derived class calls first and then derived of bse class.
Monday, October 5, 2009
Q: Explain Memory allocation in Recursive function
A: Recursive Function: The function which call itself, and terminate with the terminate condition.
For understanding the memory allocation, please go through the given example:
Factorial of N = 3;
function fact(N){
if(N==1)
return 1
else
return N*fact(N-1)
}
In order to understand how recursive functions use the Stack, we will walk through how the second algorithm above works. For your convenience, it is reproduced below.
if(N==1) return 1
else return N*fact(N-1)
Let us assume we want to find the value of 3!, which is 3 x 2 x 1 = 6. The first time the function is called, N holds the value 3, so the else statement is executed. The function knows the value of N, but not of fact(N-1), so it pushes N (value=3) on the stack, and calls itself for the second time with the value 2. This time round too the else statement is executed, and N (value=2) is pushed on the stack as the function calls itself for the third time with the value 1. Now the if statement is executed as n==1, so the function returns 1. Since the value of fact(1) is now known, it reverts back to it's second execution by popping the last value (2) from the stack and multiplying it by 1. This operation gives the value of fact(2), so the function reverts to it's first execution by popping the next value (3) from the stack, and multiplying it with fact(2), giving the value 6, which is what the function finally returns.
From the above example, we see that
The function runs 3 times, out of which it calls itself 2 times. The number of times that a function calls itself is known as the recursive depth of that function.
Each time the function calls itself, it stores one or more variables on the Stack. Since the Stack holds a limited amount of memory, functions with a high recursive depth may crash because of non-availability of memory. Such a condition is known as Stack Overflow.
Recursive functions usually have a terminating condition. In the above example the function stops calling itself when n==1. If this condition were not present, the function would keep calling itself with the values 3,2,1,0,-1,-2... and so on for infinity. This condition is known as Endless Recursion. All recursive functions go through 2 distinct phases. The first phase, Winding, occurs when the function is calling itself and pushing values on the Stack. The second phase, Unwinding, occurs when the function is popping values from the stack.
Q: When we use delete ptr, it deletes only one object but when we use delete[] ptr delete all object, how?
A: When you use new, two things happen. First, memory is allocated (via the function operator new. Second, one or more constructors are called for that memory. When you use delete, two other things happen: one or more destructors are called for the memory, then the memory is deallocated (via the function operator delete). The big question for delete is this: how many objects reside in the memory being deleted? The answer to that determines how many destructors must be called.
Actually, the question is simpler: does the pointer being deleted point to a single object or to an array of objects? The only way for delete to know is for you to tell it. If you don't use brackets in your use of delete, delete assumes a single object is pointed to. Otherwise, it assumes that an array is pointed to:
string *stringPtr1 = new string;
string *stringPtr2 = new string[100];
...
delete stringPtr1; // delete an object
delete [] stringPtr2; // delete an array of
// objects
The rule, then, is simple: if you use [] when you call new, you must use [] when you call delete. If you don't use [] when you call new, don't use [] when you call delete.
Q: What could be the reason of having error on release mode, even it is building fine in debug mode?
A: Debug and Release are different configurations for building your project. As the name implies, you generally use the Debug mode for debugging your project, and the Release mode for the final build for end users. The Debug mode does not optimize the binary it produces (as optimizations can greatly complicate debugging), and generates additional data to aid debugging. The Release mode enables optimizations and generates less (or no) extra debug data.
Because the release and debug versions run from different folders, then any code that uses relative paths may behave differently, because the relative paths may be different.
Q: When Vtable gets created?
A: Vtable will be created at the time of compilation. And Vptr would be created at the time of object creation.
Q: Why we can not have virtual constructor?
A: We call a virtual function to achieve type - specific behaviour when we have a pointer or reference to an object but you don't know what the real type of object is . We call a constructor only when you dont yet have an object but you know exactly what type you would like to have.
Q: What problem does the namespace feature solve?
A: Multiple providers of libraries might use common global identifiers causing a name collision when an application tries to link with two or more such libraries. The namespace feature surrounds a library’s external declarations with a unique namespace that eliminates the potential for those collisions.
This solution assumes that two library vendors don’t use the same namespace identifier, of course.
Q: Explain the ISA and HASA class relationships. How would you implement each in a class design?
A: A specialized class "is" a specialization of another class and, therefore, has the ISA relationship with the other class. An Employee ISA Person. This relationship is best implemented with inheritance. Employee is derived from Person. A class may have an instance of another class. For example, an employee "has" a salary, therefore the Employee class has the HASA relationship with the Salary class. This relationship is best implemented by embedding an object of the Salary class in the Employee class.
Q: When is a template a better solution than a base class?
A: When you are designing a generic class to contain or otherwise manage objects of other types, when the format and behavior of those other types are unimportant to their containment or management, and particularly when those other types are unknown (thus, the genericity) to the designer of the container or manager class.
Q: What is a mutable member?
A: One that can be modified by the class even when the object of the class or the member function doing the modification is const.
Q: What is an explicit constructor?
A: A conversion constructor declared with the explicit keyword. The compiler does not use an explicit constructor to implement an implied conversion of types. It’s purpose is reserved explicitly for construction.