473,395 Members | 1,656 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,395 software developers and data experts.

where to allocate memory

gc
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);
Nov 13 '05 #1
12 5585
"gc" <gu**********@yahoo.com> wrote:
While writing the function:
1] Should I allocate the memory for c within the function and
return the allocated memory?
or,
2] Should I allocate the memory outside the function and then
pass it as a parameter?


Both are valid solutions in C. I generally prefer the latter form
as it gives the caller more control over how they want to manage
the memory. (Perhaps using an automatic array rather than malloced
storage). I think it also looks cleaner to have the malloc and its
corresponding free in the same function.

double a = malloc(n * sizeof *c);
double b = malloc(n * sizeof *c);

double c = malloc(n * sizeof *c);
if(a && b && c)
{
/* set up a, b */
solve(a, b, c, n);
/* use c */
free(a);
free(b);
free(c);
}

Or:

double a[] = {1, 2 /* ... */};
double b[] = {1, 2 /* ... */};
double c[sizeof a / sizeof *a];
solve(a, b, c, sizeof a / sizeof *a);
/* use c */

--
Simon.
Nov 13 '05 #2
gc wrote:
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?
If you like.
something that leads to
double *solve(const double *a,const double *b,int n)
{
double *c;
/*blah blah*/
c=malloc(n*sizeof(*c));
if(c != NULL)
{
/*blah blah*/
}
return c;
}

or,

2] Should I allocate the memory outside the function and then pass it
as a parameter?
If you like.

void solve(const double *a,const double *b,double *c,int n);
/****/
c=malloc(n*sizeof(*c));
solve(a,b,c,n);


It's a design decision that only you can make. But I would look at it this
way - if you're going to need many solutions to different problems to exist
at the same time, then probably you'll find it more convenient for the
function to allocate the memory. If, on the other hand, your typical usage
scenario is that you solve /one/ problem, then another, then another,
without the solutions needing to co-exist, then it may be handier to pass
in the memory. That way, you can re-use it if you wish. Alternatively, pass
in a pointer to the memory, and get solve() to resize it as appropriate.

--
Richard Heathfield : bi****@eton.powernet.co.uk
"Usenet is a strange place." - Dennis M Ritchie, 29 July 1999.
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
K&R answers, C books, etc: http://users.powernet.co.uk/eton
Nov 13 '05 #3
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.

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.

But if you're just writing some small, quick app, there's probably no
difference.

"gc" <gu**********@yahoo.com> wrote in message
news:79**************************@posting.google.c om...
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);

Nov 13 '05 #4
On Thu, 6 Nov 2003 18:01:06 +1100, "Simon Biber" <ne**@ralminNOSPAM.cc> wrote:
double a = malloc(n * sizeof *c);
double b = malloc(n * sizeof *c);

double c = malloc(n * sizeof *c);
if(a && b && c)
{
/* set up a, b */
solve(a, b, c, n);
/* use c */
free(a);
free(b);
free(c);
}


What if a failed, you wouldn't be freeing the other guys? I still prefer the
"goto to the function trailer" approach.
Nov 13 '05 #5
On Thu, 06 Nov 2003 12:48:51 +0400, rihad <ri***@mail.ru> wrote:
On Thu, 6 Nov 2003 18:01:06 +1100, "Simon Biber" <ne**@ralminNOSPAM.cc> wrote:
double a = malloc(n * sizeof *c);
double b = malloc(n * sizeof *c);

double c = malloc(n * sizeof *c);
"Oh, *pointers* are simple - it's *typing* that's difficult. :-)"
if(a && b && c)
{
/* set up a, b */
solve(a, b, c, n);
/* use c */
free(a);
free(b);
free(c);
}


What if a failed, you wouldn't be freeing the other guys? I still prefer the
"goto to the function trailer" approach.


Namely:
double a = malloc(n * sizeof *c);
double b = malloc(n * sizeof *c);

double c = malloc(n * sizeof *c);
if(!(a && b && c))
goto nomem;
/* set up a, b */
solve(a, b, c, n);
/* use c */

nomem:
free(a);
free(b);
free(c);
}

Nov 13 '05 #6
gc wrote:

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? or,

2] Should I allocate the memory outside the function and then pass it
as a parameter?


I prefer #2.
1 It's easier to remember to write a call to free,
if you've just written the call to malloc.
2 If the function is recursive, you save a lot of allocating.
3 The function is more versatile.
It's possible that sometime, you may get a chance to pass
the function an automatic array, instead.
--
pete
Nov 13 '05 #7


rihad wrote:
On Thu, 06 Nov 2003 12:48:51 +0400, rihad <ri***@mail.ru> wrote:

On Thu, 6 Nov 2003 18:01:06 +1100, "Simon Biber" <ne**@ralminNOSPAM.cc> wrote:

double a = malloc(n * sizeof *c);
double b = malloc(n * sizeof *c);

double c = malloc(n * sizeof *c);

"Oh, *pointers* are simple - it's *typing* that's difficult. :-)"

if(a && b && c)
{
/* set up a, b */
solve(a, b, c, n);
/* use c */
free(a);
free(b);
free(c);
}
What if a failed, you wouldn't be freeing the other guys? I still prefer the
"goto to the function trailer" approach.


Yes, that should be a concern which this code does not handle.
However, the code snippet above will not even compile for other
reasons.

Namely:
double a = malloc(n * sizeof *c);
double b = malloc(n * sizeof *c);

double c = malloc(n * sizeof *c);
Why do you repeat the flawed code?
a, b, c should all be a pointer type.
The variable c is being used before it has been declared.
Namely: A lot of errors in this short snippet of code.
if(!(a && b && c))
goto nomem;
/* set up a, b */
solve(a, b, c, n);
/* use c */

nomem:
free(a);
free(b);
free(c);
}


There is no need to do a goto here. Simply free a, b, and c
in the "trailer".

#include <stdio.h>
#include <math.h>
#include <stdlib.h>

void solve(double *a, double *b, double *c, double n);

int main(void)
{
double n = 9000.00;
double *a = malloc(sizeof *a);
double *b = malloc(sizeof *b);
double *c = malloc(sizeof *c);

if(a && b && c)
{
solve(a, b, c, n);
printf("*a = %f\n*b = %f\n*c = %f\n",*a,*b,*c);
}
free(a);
free(b);
free(c);
return 0;
}

void solve(double *a, double *b, double *c, double n)
{
*a = log(n);
*b = log10(n);
*c = *a-*b;
printf("log(%.2f) = %f\n",n,*a);
printf("log10(%.2f) = %f\n",n,*b);
printf("log(%.2f) - log10(%.2f) = %f\n\n", *a, *b,
log(*a)-log(*b));
return;
}

--
Al Bowers
Tampa, Fl USA
mailto: xa******@myrapidsys.com (remove the x to send email)
http://www.geocities.com/abowers822/

Nov 13 '05 #8
gu**********@yahoo.com (gc) wrote in message news:<79**************************@posting.google. com>...
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?
<snip code>
or,

2] Should I allocate the memory outside the function and then pass it
as a parameter?


<snip>

you've had quite few answers by now. I'll only add I'd favour 2] by
the old design rule that every function should do only one thing. Have
a separate allocator.
--
Nick Keighley
Nov 13 '05 #9
"rihad" <ri***@mail.ru> wrote:
On Thu, 06 Nov 2003 12:48:51 +0400, rihad <ri***@mail.ru> wrote:
On Thu, 6 Nov 2003 18:01:06 +1100, "Simon Biber" <ne**@ralminNOSPAM.cc> wrote:
double a = malloc(n * sizeof *c);
double b = malloc(n * sizeof *c);

double c = malloc(n * sizeof *c);


"Oh, *pointers* are simple - it's *typing* that's difficult. :-)"


Indeed. Thanks, Richard :-(

--
Simon.
Nov 13 '05 #10
Greetings.

In article <fw***************@newssvr14.news.prodigy.com>, Roose wrote:
If there's no good reason to allocate it in the function, then I prefer to
have the caller allocate.
To what does "it" refer?
"gc" <gu**********@yahoo.com> wrote in message
news:79**************************@posting.google.c om...
1] Should I allocate the memory for c within the function and return
the allocated memory?


Oh, I see.

Please don't top-post.

Regards,
Tristan

--
_
_V.-o Tristan Miller [en,(fr,de,ia)] >< Space is limited
/ |`-' -=-=-=-=-=-=-=-=-=-=-=-=-=-=-= <> In a haiku, so it's hard
(7_\\ http://www.nothingisreal.com/ >< To finish what you
Nov 13 '05 #11
On 5 Nov 2003 20:54:57 -0800, gu**********@yahoo.com (gc) wrote:
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 <snip>or,

2] Should I allocate the memory outside the function and then pass it
as a parameter?


It will work either way, but in general, I'd recommend the second
approach as being less error-prone. Rule of thumb: whenever possible,
malloc and the associated free should be in the same scope.

--
Al Balmer
Balmer Consulting
re************************@att.net
Nov 13 '05 #12
On 2003-11-06, Roose <no****@nospam.nospam> wrote:
....
[top posting fixed]
....
"gc" <gu**********@yahoo.com> wrote in message
news:79**************************@posting.google.c om...
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
Nov 13 '05 #13

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

37
by: Curt | last post by:
If this is the complete program (ie, the address of the const is never taken, only its value used) is it likely the compiler will allocate ram for constantA or constantB? Or simply substitute the...
17
by: Jonas Rundberg | last post by:
Hi I just started with c++ and I'm a little bit confused where stuff go... Assume we have a class: class test { private: int arr; };
8
by: M. Moennigmann | last post by:
Dear all: I would like to write a function that opens a file, reads and stores data into an 2d array, and passes that array back to the caller (=main). The size of the array is not known before...
4
by: marora | last post by:
I have created class definition which contains a charater pointer as one of it's data memeber. The objective is to read some data from a file, and assign it to a data member; Size of data is...
14
by: raghu | last post by:
Hello , This is Raghu. I have a problem in declaring a structure. Consider struct hai{ int id; char sex; int age; }; here when a variable is instianted for this structure then immediately
2
by: lovecreatesbea... | last post by:
If the built-in operator keyword new doesn't allocate memory on heap and it calls global operator new (::operator new) or class member operator new to do that. What are the two kinds of operator...
14
by: karthikbalaguru | last post by:
Hi, In the case of heap , to keep track of a single chunk of memory it requires 8 bytes of information. That is, it requires 4 bytes to hold the size, and 4 bytes to hold the pointer to the next...
11
by: Bryan Parkoff | last post by:
I want to know how much static memory is limited before execution program starts. I would write a large array. The large array has 65,536 elements. The data size is double word. The static...
1
by: ulrik | last post by:
Hi, I've read somewhere that there is an upper limit of memory allocation within a single AppDomain of 800 MB. Is this true? If yes, is there anything I can do to get around this? My...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.