Advanced C topics – Part2

Some of the things which could not fit into the previous post will be explained here.

In the previous post related to advanced C topics we were discussing about comparaison between arrays and pointers, how is an array of characters different than a pointer to an array of characters, how can arrays be passed as parameters and how you can avoid being tricked by the way bi-dimensional arrays are passed as parameters. In this post I will try to outline how can an array be returned as a value from a function and what’s the use of pointers to functions.

Let me start with the first item: how to return arrays from functions. Just have a look at the following code snippet:

char* function (int n)
{
char buffer[200];
….
return buffer;
}

A dangerous mistake that is hidden in this code is that this function returns a pointer to a local variable. As long as the value returned is a pointer, this one affects directly the variable pointed to, not a copy of it, and local variables are going out of scope when function ends. Basically this function is returning something that doesn’t exist anymore. If the function would return a value, not a pointer or an address, this is another topic.

There would be two solutions to circumvent this issue: either to declare the returned values as static, in this case we’ll see that many other problems will arise, or to dynamically allocate it, via malloc (don’t say new, we are talking solely about C here)

In case you choose the static approach you will have problems if you want to keep different copies of the returned values at different moments of time. Let me explain. As you may already know a local static variable is one which has as a scope only its function but as lifetime the complete execution of the program, it persists after its function exits.

char* function (int n)
{
static char buffer[200];
….
return buffer;
}

In your program if you want something like this:

char *c1, *c2;
c1 = function(2);
c2 = function(10);
printf (“%s %s”, c1, c2); // you’ll be surprised to see that both values printed are the same
// and have a value of function(10)

Usually a general solution to overcome all kind of drawbacks is to dynamically allocate the returned value:

char* function (int n)
{
char buffer = malloc(20);
….
return buffer;
}

Two big issues come into play when using this approach:

  1. each time you dynamically allocate memory you are in total control of your variable’s lifetime. Be aware when call multiple times that function to apply the corresponding free method, otherwise you’ll risk to run out of memory (Remember: dynamically allocated variables are not freed automatically)
  2. second thing … the caller of the function has to check whether or not the allocation was successful or not (in case it didn’t succeeded a NULL pointer will be returned)

I have seen somewhere on come C/C++ programming forums a different approach for this issue. It was making use of a structure and it was relying on the aspect that structures can be returned as value from a function. Below is the example code:

struct mystruct {
int vector[20];
}

struct mystruct foo()
{
struct mystruct bar;

return bar;
}

What about pointers to functions? What are they useful for? This is generally considered one of the most sophisticated items concerning pointers. It is treated at the end of a programming class about pointers or is completely left apart. To be honest I never learned in faculty about function pointers.
Before answering those question it is worthwhile to trace the difference in between how a function which returns a pointer is declared and how a pointer to a function is declared:


int *function (int m, int n); // this is a function returning a pointer
int (*function) (int m, int n); // this is a pointer to a function

In the second case function acts like a variable, well a function by itself can act as a variable in the way that you can assign its value to another variable, but a pointer to a function can be passed as a parameter to another function. Actually this is the great advantage of function pointers.

But the thing above is just a declaration of a pointer to a function which returns an int and takes two int’s as parameters. The pointer can be assigned to indicate a specific function by this:

int function (int a, int b);
int (*pointer_function) (int, int) = &function;

when you want to place pointer_function inside a function’s list of arguments, you have to write something like this:

int another_function (int x, int y, int (*pointer_function)(int, int));

Well… OK but that’s not all about function pointers, their usage does not die here.

What I think is the most important feature of function pointers, is the fact that they simulate some kind of polymorphism in C. There are many advised voices who claim that function pointers can be avoided in C++ due to the fact that the polymorphism by itself, via virtual functions, are making the same job.   Their (function pointers) use is when you cannot decide which function to execute at compile-time . The most classical example (which can be found also in Ritchie & Kernighan – C bible) is the one with qsort function.

How can this sort some items of a filed without knowing their type?

Simple … using function pointers, qsort receives a parameter which is … you guessed … a pointer … to a function which takes as arguments two void pointers.

The notorious library function strcmp has the big disadvantage that it computes only characters, it doesn’t help you if you have numbers to sort.  An example is provided below:

...
void qsort (void* field, int nEelements, int sizeOfAnElement, int(*CmpFunction)(void*, void*));
int CmpFunction (void * a, void* b)
{
float* a1 = (float*) a;
float* b1 = (float*) b;
if (*a1 > *b1 ) return 1;
else if (*a1 == *b1) return 0;
else return -1;
}

void main()
{
float field [100];
qsort ((void*) field, 100, sizeof(field[0]), CmpFunction)
}

If you are a C expert probably those things would seem trivial for you, so it makes no sense reading those two posts (Advanced C topics Part 1& 2), but if you’re still in the learning phase, I think you’ll find here interesting and new things. Personally, I didn’t had a deep understanding of all those topics discussed in those posts and in my opinion it worth having a look here. Generally those things are briefly and superficially addressed in faculty and they deserve a deeper understanding if you seek for a senior C programmer position.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: