....
[top posting fixed]
....
gc said:
I am writing a function that given nx1 vector a and a nx1 b solves a
system of equations f(a,c)=b for a nx1 c.
While writing the function:
1] Should I allocate the memory for c within the function and return
the allocated memory?
something that leads to
double *solve(const double *a,const double *b,int n)
{
double *c;
/*blah blah*/
c=malloc(n*sizeof(*c));
/*blah blah*/
return c;
}
or,
2] Should I allocate the memory outside the function and then pass it
as a parameter?
void solve(const double *a,const double *b,double *c,int n);
/****/
c=malloc(n*sizeof(*c));
solve(a,b,c,n);
If there's no good reason to allocate it in the function, then I prefer to
have the caller allocate. You might always remember to free, but others
might not. If you make them write the malloc, they won't forget.
Please don't top post in this newsgroup. Thanks.
Also, the caller allocating is slightly better from a code reuse point of
view. Your solver is now tied to malloc, whereas some people use different
memory management schemes. I have no idea what system you're on, but if you
use multiple heaps or anything like that, you want to have the caller
allocate.
This is not necessarily true. The provider of the library can expose
an interface to allow the client of the library to tweak the allocator.
/*
* By default, the library uses malloc and free to handle its
* dynamic memory allocation requirements. If you wish to
* change the default allocator, use this function. Both
* m (e.g., malloc) and f (e.g., free) must point to valid
* functions. If either is NULL, no change will take effect.
*/
void set_allocator(void *(*m)(size_t), void (*f)(void *));
This could be useful if the library is using a data structure that
requires multiple allocations. If the library does not want to
expose the nature of the data structure to the library client, then
the library has to be the one to construct the data structure.
It could also be useful if the library is utilizing a reference
counting mechanism, where it is the job of the reference release
function to reap any allocated resources when the count gets to
0.
The library might maintain pointers, e.g.:
/* mylib.c */
#include <stdlib.h>
/* ... */
static void *(*mymalloc)(size_t) = malloc;
static void (*myfree)(void *) = free;
/* ... */
void
set_allocator(void *(*m)(size_t), void (*f)(void *))
{
if (m == 0 || f == 0) {
return;
}
mymalloc = m;
myfree = f;
}
-- James