Monday, January 28, 2008

Dynamic Memory Allocation on Stack

How to dynamically allocate memory in the stack? Use alloca() is an option:

f()
{
int * i = (int *)alloca(sizeof(int));
}

alloca() allocates on the current stack frame. Anyway it makes no sense to allocate dynamic mem in stack? It does.

If you want to dynamically allocate some memory but do not take the hassle to release it at all exit points. One way to do it is like this.

Another way is to use a smart pointer. However, the second solution is not available in C.

Stack meant for dynamic memory for the CURRENT context. But then we have to make sure the size of the object. If it is a C++ object, then need to use the displacement new method I described before. I believe this is more useful for dynamic array, though dynamic array is supported by C99. For C++, smart pointer is better, or dynamic array. But for C, this is somehow useful.

Displacement new operator in C++

Have you ever seen C++ code like this?

void *spc = memPool->Alloc(sizeof(ObjectC));

ObjectC * content = new (spc) ObjectC();

This is really hard-to-read code for many beginners. It looks this piece of code couldn't even pass the symtax check.

This is called "placement new". That is, the first line allocate the memory block at a specific location in memory (which should you implement in the Alloc() method of your memory pool object). The second lilne takes the pointer to the allocated memory block as a parameter to new operator (yes, new operator could take a parameter). So new will use this memory block to place the new object, instead of allocating by itself. This way, the new object is allocated at a specific location.

Why you can't directly do this way?

ObjectC * content = (ObjectC *) memPool->Alloc(sizeof(ObjectC));

Since then the constructor is not called. You should NEVER allocate a new object by simple allocate memory for it.

That's a special symtax for new. Last thing is: try not to use thi symtax unless you really need it. If you use this symtax, make sure you always allocate sufficient and correctly aligned memory for the object.

Also, you are responsive for the destruction of this object. Neither compiler nor run-time will take care of that. So, write down the line somewhere after you finished your object:

content->~ObjectC();

Monday, January 14, 2008

Type Casting between Basic Types

We have a double type variable and need to pass it to another module. However, we only have a communication API that can pass a single uint32_t. How can we do this without losing any precision?

Using the following C style casting is not working:

double d = 3.14;
int i = (int) d;

In this case i = 3 and we lost the decimals.

Using C++ style static_cast has the same effect:

int i = static_cast(d);

The C++ reinterpret_cast seems to work how ever if you write

int i = reinterpret_cast(d);


it is not working. reinterpret_cast can only cast between pointer types.

So, we got the hint here: reinterpret it as a pointer!

The correct solution then works as this way:

nt i = *(reinterpret_cat<*int>(&d));

If you prefer the C style, this could be neater:

int i = *((int *)(&d));

When we need to decode it, simple do the reverse way:

double newD = *((double *)(&i));