Re: [C] freeing memory allocated in a function

From: Arthur J. O'Dwyer (ajo_at_nospam.andrew.cmu.edu)
Date: 05/31/04


Date: Sun, 30 May 2004 19:07:39 -0400 (EDT)


On Sun, 30 May 2004, Marlene Stebbins wrote:
>
> I'm using the code below to illustrate a situation that always
> puzzles me when memory is allocated dynamically in a function.
> There are two calls to malloc in the program, one in main() and
> the other in polar2cart(), but only one call to free.

  That is a bug. Each 'malloc' should have a corresponding 'free'.
In this case, you have an extra unused 'malloc' call that needs to
be removed.

> Have I correctly freed all dynamically allocated memory here? If
> not, where should the memory allocated in the function be freed?

  The memory allocated in the function should be freed once it
is no longer useful. If the function itself can't guarantee that
it will be able to free the memory itself, then it should take care
to document the allocation so that the programmer will remember to
free the returned block at an appropriate time (in this case, at
the end of 'main').

> /* convert polar to Cartesian coordinates */
> #include <stdio.h>
> #include <stdlib.h>
> #include <math.h>
> #define PI 3.14159265358979323846

  FYI, this is more precision than you'll ever need in practice,
and probably more precision than your implementation can provide
anyway. 3.1415927 is what I generally use. This is not relevant
to your bug, though.

> double* polar2cart(double r, double theta);
>
> int main(int argc, char* argv[])
> {
> double r, theta;
> double* xy;
>
> if(argc != 3)
> {
> fprintf(stderr, "enter radius and angle\n");
> exit(EXIT_FAILURE);
> }
> r = strtod(argv[1], NULL);
> theta = strtod(argv[2], NULL);
> xy = malloc(2 * sizeof(*xy));

  'sizeof' is not a function, but an operator; the extra parentheses
are... well... extra! Remove them.
  And then remove the entire line, while you're at it. It just
assigns a value to 'xy'...

> xy = polar2cart(r, theta);

...that is promptly overwritten with the return value of the
'polar2cart' function. In other words, you're allocating a bunch
of memory and then throwing away the pointer that points to it.

> printf("\nx = %f y = %f\n", xy[0], xy[1]);
> free(xy);

  This is correct.

> return 0;
> }
>
> double* polar2cart(double r, double theta)
> {
> double cartx, carty, radians;
> double* cartxy;
>
> cartxy = malloc(2 * sizeof(*cartxy));
> radians = theta * (PI / 180.0);
> cartx = r * cos(radians);
> carty = r * sin(radians);
> cartxy[0] = cartx;
> cartxy[1] = carty;

  The intermediate variables serve no purpose. Lose them.

     cartxy[0] = r*cos(radians);
     cartxy[1] = r*sin(radians);

>
> return cartxy;
> }

  Each 'malloc' needs a corresponding 'free'. If you find you
have too many 'malloc's, start looking for the ones that never
get freed. There's your memory leak. Sometimes the fix is
trivial, as in this case; sometimes it's really tricky.

HTH,
-Arthur



Relevant Pages

  • Re: Simple question about headers and malloc!
    ... Therefore I am making all of its declarations ... memory (using malloc) and then exit back to main. ... allocation, I get data strored from the second allocation... ...
    (microsoft.public.vc.language)
  • Re: Simple question about headers and malloc!
    ... Therefore I am making all of its declarations ... memory (using malloc) and then exit back to main. ... allocation, I get data strored from the second allocation... ...
    (microsoft.public.vc.language)
  • Re: xmalloc string functions
    ... than a NULL return from malloc(). ... Memory is quite a different kind of resource. ... I try to write my code so any allocation failure is handled ... its not likely that one will be more susceptible to failure than the other. ...
    (comp.lang.c)
  • Re: A solution for the allocation failures problem
    ... reduce the effort involved in managing memory. ... Releasing such buffer may not effect the ability of malloc() to return ... says it releases the memory for subsequent allocation, ... Dealing with the failure "at point of failure" isn't inherently evil. ...
    (comp.lang.c)
  • Simple question about headers and malloc!
    ... Therefore I am making all of its declarations ... memory (using malloc) and then exit back to main. ... allocation, I get data strored from the second allocation... ...
    (microsoft.public.vc.language)