Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Best practice for allocating memory for use by a function — malloc inside or outside?

Tags:

c

malloc

During my experience with C coding, I've seen 2 ways of passing arguments for functions:

  1. malloc before calling functions

  2. malloc inside functions (variable is not initialized before calling function)

I, particularly, prefer the second form. But while I'm the only one to code my program, I know that, but some else could not know, and could lead to 2 malloc, and leak of memory.

So, my question is: What's the best practice for this?

like image 866
rafaeldomi Avatar asked Nov 18 '12 17:11

rafaeldomi


People also ask

Where does malloc function allocate memory?

In C, the library function malloc is used to allocate a block of memory on the heap. The program accesses this block of memory via a pointer that malloc returns. When the memory is no longer needed, the pointer is passed to free which deallocates the memory so that it can be used for other purposes.

Can I malloc inside a function?

To malloc inside a function, process the code, and then return the pointer to that heap space. To malloc outside of a function, i.e. within main(), and passing that pointer to a void function for processing.

Which standard function is used to clear memory allocated by the malloc () function?

Syntax of calloc() Function: After the memory space is allocated, then all the bytes are initialized to zero. The pointer which is currently at the first byte of the allocated memory space is returned.

Which allocation is faster malloc or calloc?

Calloc is slower than malloc. Malloc is faster than calloc. It is not secure as compare to calloc. It is secure to use compared to malloc.


3 Answers

Allocating memory in the caller is more flexible, because it allows the caller to use static or automatic storage instead of dynamic allocation, and eliminates the need to handle the case of allocation failure in the callee. On the other hand, having the caller provide the storage requires the caller to know the size in advance. If the size is compiled into the caller as a constant and the callee is in a library that's later updated to use a larger structure, things will break horribly. You can avoid this, of course, by providing a second function (or external variable in the library) for retrieving the necessary size.

When in doubt, you can always make two functions:

  1. The main function that uses caller-provided storage.
  2. A wrapper function which allocates the right amount of storage, calls the function in #1 using it, and returns the pointer to the caller.

Then the caller is free to choose whichever method is more appropriate for the particular usage case.

like image 162
R.. GitHub STOP HELPING ICE Avatar answered Nov 03 '22 08:11

R.. GitHub STOP HELPING ICE


I personally strongly favor your first proposition (whenever it is possible) for orthogonality. Take the following example:

extern void bar(int *p, int n);

void foo(int n)
{

   int *p = malloc(n * sizeof *p);

   // fill array object
   bar(p, n);

   // work with array elements

   /* ... */

   // array no longer needed, free object
   free(p);
}

This is orthogonal. malloc and free are called in the same lexical scope which is clean and readable. Another advantage is you can pass to bar function an array with a different storage duration for example an array with automatic or static storage duration. You let bar function focus only on the work it has do and let another function manage the array allocation.

Note that this is also how all Standard C functions work: they never appear to call malloc.

like image 36
ouah Avatar answered Nov 03 '22 10:11

ouah


The criteria I'd use for deciding are:

  • If the code outside the called function can know how much memory to allocate, then it is better to have the calling code allocate the memory.

  • If the code outside the called function cannot know how much memory to allocate, then the called function must do the memory allocation. It is likely then that there will be a second function available to release the memory returned by the first function (the 'called' function), unless it is just a single free() that's needed. The function documentation should make this clear.

For example, if the called function is reading a complete tree structure from a file, the function will have to allocate the memory. But, there will also be a companion function for releasing the memory (since the called code knows how to do it and the calling code shouldn't need to know).

On the other hand, if the called function is reading a simple list of integer and floating point values into a fixed size structure, it is far better to make the calling function allocate the memory. Note that I skipped 'strings'! If the strings are of a fixed size in the structure, then the calling function can do the allocation, but if the strings are of variable size, then probably the called function does the allocation.

The Standard C Library has functions like fgets() which expect the calling code to allocate the memory to be used. The calling sequence tells fgets() how much space is available. You run into problems if you didn't provide enough memory. (The problem with fgets() is that you may only get the start of a line of text, not the whole line of text.)

The POSIX 2008 Library provides getline() which will allocate enough space for the line.

The asprintf() and related functions (see TR24731-2) allocate memory as required. The snprintf() function does not — it is told how much space there is available, it uses no more than that, and says how much it really needed, and it is up to you to note if you didn't provide enough space and do something about it (allocate more space and try again, or blithely ignore the truncated value and continue as if nothing went wrong).

like image 41
Jonathan Leffler Avatar answered Nov 03 '22 08:11

Jonathan Leffler