In a comment on Google+ to my previous post The Size Of Strings, my colleague Lee Berg asked:
Other than sizeof(), what is the best way to ensure a safe implementation?
This is a damn good question because a built-in function to retrieve the size of the memory allocated is the thing that I would like to have in C. On the other hand, I know that this would limit (or be error prone with) some kinds of memory managements.
With "some kinds of memory management" I mean all the dirty tricks that C programmers use to do but also standard usages. Look at this example:
void foobar(int *something);
int main()
{
int myarray[10];
foobar(&myarray[5]);
return 0;
}
If some magic mechanism to determine the size of allocated memory would exist, it would be in trouble if asked to return a value that makes sense when used inside foobar()
.
The GLib Solution
The technique used by GLib for gchars is quite interesting, even if not particularly original. If you look for the basic type, you'll find this:
#define gchar char
Where is the trick? Simply, the functions that return a pointer to gchar allocate some more bytes at the beginning of the string with the allocated size and then return a pointer to the beginning of the "real" string. In this way you can use gchar *
almost whenever a char *
is needed.
The drawback is that you have to remember to use g_free()
and other GLib specific functions when you need to deal with the pointer itself.
My Solution
What I usually do is to create a structure with three members: the pointer to the allocated memory, and two integers (or size_t). The first represents the number of allocated items of the array and the second is the number of used items. Something like this:
struct mystruct {
unsigned int max;
unsigned int used;
int *myarray;
};
This is nothing special, but it allows to keep track of both the reserved (max
) and the filled (used
) items of the array. In this way it's easier to manage arrays that can grow over time and re-allocate when needed.
Image taken from Wikimedia Commons (public domain).