C++ Blog

Monday, April 16, 2007

When "constructor initializer list" is mandatory?

1) To initialize const data member
2) To initialize reference data member
3) To call a non-default constructor in base class
4) To call a non-default constructor for a member object

For example

class Game {
GameBoard gb;
// Composition
public:
// Default GameBoard constructor called:
Game() { cout << "Game()\n"; }
// You must explicitly call the GameBoard
// copy-constructor or the default constructor
// is automatically called instead:
Game(const Game& g) : gb(g.gb) { cout << "Game(const Game&)\n"; }
Game(int) { cout << "Game(int)\n"; }
Game& operator=(const Game& g) {
// You must explicitly call the GameBoard
// assignment operator or no assignment at
// all happens for gb!
gb = g.gb;
cout << "Game::operator=()\n";
return *this;
}
};

****** Code sample taken from Thinking in C++ by Bruce Eckel **********

When "Copy Constructor" is invoked?

1) When an object is created from an existing object
2) When an object is passed by value
3) When an object is returned by value

Tuesday, April 03, 2007

Explicitly calling destructor?

If the object is created on the stack then destructor will be called but when the object goes out of scope the destructor is called again.With the object on heap(created with new operator) the destructor will be executed but the memory won't be released.
So explicitly call the destructor for a object only when that object is created with the "placement" new operator, because here you don't want to release the memory but still you want to execute destructor to release all the resources holded by it.

How to call a destructor?

To call the destructor manually use the following syntax
ClassA ObjA;
ObjA.~A();

The following are incorrect
~ObjA(); // This might call complement operator for an object
~ClassA(); // This creates temporary object and applies complement to it

Monday, April 02, 2007

"GARBAGE COLLECTOR" a Curse or a Bless?

What is "Manual Memory Management"?
In the manual memory management the user himself should take care of allocating memory for objects and releasing the memory when its not needed anymore. C++ supports manual memory management because it doesn't have any mechanism which collects memory automatically when it is not needed.

What is "Garbage Collector"?
Garbage collector is automated way doing memory management. In this case the user needs to allocate memory but he doesn't need to worry about the re-claiming memory becaues garbage collector does that automatically. C# and Java falls under this category.

Manual Memory Management
A Bless

1) We don't need to keep track of all active objects or periodically look for memory which can be re-claimed. (This is needed for Garbage Collector)
2) More control over memory allocation and de-allocation. You can reclaim memory when ever needed by using a "delete" operator. Which in turn calls the destructor so we can be sure that object releases all the resources before it is destroyed.

A Curse

1) Main problem with this approach is "Memory Leak" which degrades system performance and may lead to fatal errors. Failing to release allocated memory will result in memory leak.
2) Releasing memory which are pointed by other objects will result in a undefined behaviour when the other object tries to access its data. This is called as "Dangling Pointer"
3) Trying to release the same memory twice unknowingly can lead to serious error.


Garbage Collector
A Bless

1) It is very simple and safe. Simple in the sense the user doesn't need to worry about releasing object and keep track of all the objects. Safe because you don't need to release memory explicitly so you may not get in to situation of releasing same memory twice or releasing memory which is pointed by some other reference.

A Curse

1) Garbage collector needs CPU cycles for re-claiming all the unused memory. It also needs to keep track of all the objects that are in use with a datastructure or it needs to scan through the memory for finding it.
2) It makes calling the object destructor non-deterministic because of no control over the memory when it will be released. The memory is released only when the garbage collector runs and recyles the object. But it is not easy to predict when the garbage collector will run. In some systems it will start when the free memory limit threshold is reached, in some systems it is started when the CPU cycles are free.
3) Real-time applications can't use garbage collectors since allocating of CPU cycles to garbage collector could cause an event to be missed :-(.


As we can see the curse of Garbage collector is more than its blessings but this often overcomes in most of the programs, using garbage collector is a trade-off but most of the modern systems its a bless.

C++ is a mixed blessing, since you have to do manual memory management but you can also write code to do garbage collection with the power of C++.
Ref:

When "new" fails?

When you create a object with new it allocates required memory for object, calls the constructor and returns a pointer to the created object.
If it fails to allocate contiguos memory, it calls a special pre-defined function called "new_handler" function, the default functionality of the function is to throw an exception, it throws an bad_alloc exception.
The user can override the defaul new_handler function using a "set_new_handler" function defined in new.h header file. The new handler function should take no arguments and return a void.

What if, I overload "new" operator?
When the user overloads the new operator it doesn't call new_handler by default. It is tied to the default behaviour of new operator, so when the user over loads the new the user should take care of calling this function.


What I can do in new-handler?
  • The user can write code to log and error message about the memory could not be allocated and then throw error, so that it might give enough ninformation to debug the program.
  • Even we can write a "garbage collector" in that function and try to re-claim the memory.


#include <iostream>
#include <new>
using namespace std;
int count = 0;
void out_of_memory()
{
cerr << "memory exhausted after " <<>
exit(1);
}
int main() {
set_new_handler(out_of_memory);
while(1) { count++; new int[1000]; // Exhausts memory }
} ///:~
********** Code sample from Thinking in C++ by Bruce Eckel *************

"delete" operator in C++

1) delete calls the destructor for an object before it deallocates the memory.

2) delete should be called for objects that are constructed with new only, if it is used for the object that was allocated with malloc then the result is undefined.

3) delete should be called only for dynamically allocated objects should not be used for the objects in stack if it is used then the result is undefined.

4) Deleting array of objects should be used as delete[] ptr or if it used like delete ptr; it deletes only the first object and the remaining elements are not deallocated.
For example;
student *obj = new student[10];
...
...
...
delete []obj; // This is correct way to delete. delete obj; will result in deleting obj[0] alone.

5) Deleting an object twice using delete is not recommended and the result it un-defined.
For example;
student *obj = new student();
....
delete obj;
....
...
delete obj; // The result is undefined because the previous delete doesn't gurantee storing 0 in the obj.

6) deleting a object pointer with value 0 wont result an error.
For example;
student *obj = new student();
....
delete obj;
obj = 0;
...
delete obj; // This is ok because obj has 0

Tuesday, March 06, 2007

Difference between C struct and C union

C struct variable size is equal to the sum of the sizes of all the members in it. But C union variable size is euqal to the largest size of the member in it. In other words, union uses one large block equivalent to the largest member and share this memory for all the members, but struct has memory allocated for each of its members.

Difference between C struct and C++ struct

C struct can have only members, it can't have methods or access specifiers. It can't inherit a structure.
C++ struct can have members, methods and has access specifiers to restrict its access. It can inherit other structures also.

Difference between C++ struct and class

The only difference between C++ struct and class is, the members of a struct are "public" by default but in class it is "private"

Difference between C++ union and class

Difference between C++ union and class is, the members of a union are "public" by default but in class it is "private".
C++ union can have constructor, destructor but not virtual functions. They can't have virtual functions because unions can't act as a base class. Unions can't have base class also. Unions can't have static members. An object of a class with a constructor or a destructor or a user-defined assignment operator can't be a member of union.

Tuesday, November 29, 2005

Uses of Placement new operator

1) It is used to create a memory pool or buffer
2) Useful in system programming like shared memory, memory mapped IO etc.,
3) It is helpful in applications where performance and exception safe are important like embedded systems
a. Performance gain is because allocation of objects happens in the pre-allocated buffer so it is fast
b. It is exception safe because you don’t need to worry about allocation failure (since the object is constructed in pre-allocated memory)

Saturday, October 08, 2005

What is “Slicing Problem”?

class base {}
class derived: public base {}

class base baseObj;
class derived derivedObj;

baseObj = derivedObj;
/* Only baseObj features will be copied leaving all the extra features in derivedObj this is called slicing */

derivedObj = baseObj;
/* Down slicing only baseObj features will copied and all the others will have unknown values, this is not safe to do this and C++ provides an casting operator for doing this, it is called as dynamic_cast */

Pass by Reference

There will not be any splicing if we pass by reference. Slicing normally happens when one object is assigned to another. If we pass a value by reference then there is no assignment that is taking place and the objects themselves get passed as an argument. So there will be no slicing.

Slicing is not related to pointers or members, it is related with objects themselves.

What one should take care, when writing a C++ class with pointer members?

a. Mainly constructor, Copy constructor (for deep copy), assignment operator and destructor,
b. If a class which has pointer members is inherited then the destructor should be made virtual.
c. Memory leak is the main concern so de-allocation of memory is really import if there is a pointer member.

Difference between new and malloc?

1. When new is used, class constructor will be called but malloc don’t know anything about class so it just allocates chunk of bytes.
2. One disadvantage of new is that there is no way to reallocate memory. With malloc you can use realloc to extend the amount of memory.
3. new returns pointer to the object type, but malloc returns void *
4. When malloc failed to allocate memeory it returns a NULL value, but if new fails to allocate memory it throws an exception.
5. new gurantees allocating memory equivalent to the size of the object or required size.
For example;
Obj* obj = (Obj*)malloc(sizeof(int*3)); // This is allowed syntax but it may not be satisfying the memory requirement of Obj
6. new is an operator can be overloaded.

Tuesday, September 27, 2005

Difference between Reference and Pointer

Difference between Reference and Pointer

  1. Reference should be initialized and pointer need not be.

  2. Reference can’t point to NULL and pointer can.

  3. Reference can’t be changed to some other objects it is once initialized but pointer can be.

  4. Pointer can be incremented or decremented and subjected to any pointer arithmetic operations, but reference can’t.