Question

I have one question regarding design of my application. Here's the pseudo code:

char* buffer_to_be_filled = (char*) malloc(somesize);
fill_the_buffer(buffer_to_be_filled);
free(buffer_to_be_filled);

The problem is that I don't know how much size fill_the_buffer requires.

I was thinking about the solution inside the fill_the_buffer function. I could maybe realloc the space inside when needed; the problem is, is there any way to find out how much space I have available?

How is this usually solved? I think that the one who allocates the buffer should also realloc the buffer as well, right?

NOTE : I'm filling the buffer using fread function, so I don't know how much space will I need.

Was it helpful?

Solution

Your function can't realloc the pointer that was passed to it, because realloc isn't guaranteed to return the same pointer it was passed (the new buffer might be too big to expand in-place). The typical solution is for the function to take a second argument specifying the size of the buffer, and to return an error code if the buffer is too small. Ideally, the error code will tell the user how big the buffer needs to be, so they can reallocate it themselves and recall the function. For example, from the man page for snprintf (which has this problem):

The functions snprintf() and vsnprintf() do not write more than size bytes (including the terminating null byte ('\0')). If the output was truncated due to this limit then the return value is the number of characters (excluding the terminating null byte) which would have been written to the final string if enough space had been available. Thus, a return value of size or more means that the output was truncated.

OTHER TIPS

It seems that fill_the_buffer() function is in a much better position to know...
- how to dimension the buffer initially and/or
- when to re-alloc the buffer and by how much.

Therefore it may be appropriate to change the API:

char * fill_the_buffer()
or maybe
char * fill_the_buffer(size_t max_amount_caller_wants)

The caller to fill_the_buffer() would still be responsible for disposing of the buffer returned by the function, but the allocation and dimensionning would be left to the function's logic.

This approach generally follow the idea of leaving implementation details to the lower level, making the upper levels more readable.

You must pass the buffer size into the fill_the_buffer function. If the buffer is not big enough, your function must return an error value (f/e -1). In case of success, your function can return the count of writen bytes. This method is common practice for the C language.

I've a suggestion if you have no problem in allocating free memory:
Allocate an initial size at the beginning of the program using malloc, (try to make a good guess for this initial allocation),then in the fill_the_buffer you may need to allocate more memory or may you don't need all allocated memory. In first case, you can allocate a suitable amount of memory (depends on to your application & your available ram) in some steps (e.g 10MB at each leakage) & then resume filling the buffer till you need more memory & repeat this while buffer fills. In second case you can simply realloc to decrease size of allocated memory of your buffer.
But take care about using realloc specially when you want to increase size of buffer, because it usually causes big overhead (It has to find's a big enough part of free memory, then copy all of old data into new part & free the old section).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top