Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Returning a malloc pointer

Tags:

c

malloc

struct

Pretty basic question here, I'm a little unsure on the passing around of memory in C.

If I have the following

CGPoint* tileForCoordinates (CGPoint position, short width, short height)
{   
   CGPoint *tileCoordinate = (CGPoint*)malloc(sizeof(CGPoint));
   tileCoordinate->xTile = (position.xPosition / width);
   tileCoordinate->yTile = (position.yPosition / height);

   return tileCoordinate;
}

and I wanted to call this in another source file or whatever, would I declare a pointer and above and return it? If so, When I call is from another class e.g.

CGPoint *currentTilePosition = tileForCoordinates(curPosition, 50, 50);

What happens to the pointer returned by malloc? Should it be freed or whats the story? :)

like image 258
some_id Avatar asked Mar 31 '11 00:03

some_id


4 Answers

To answer "what is happening to the pointer returned by malloc()?"

The pointer declared by malloc() will be a value in the stack frame of the currently executing function. When the stack frame (and thus *tileCoordinate) goes out of scope at function return, that pointer will cease to exist.

However, because you return the pointer value to the calling function, it now exists in the current stack frame (after returning). This value is referenced by the variable *currentTilePosition.

The memory allocated by malloc() is a completely different story; dynamically allocated memory exists on the heap. You should free any memory that you allocate in the same implementation that performs allocation. This implies calling free() on currentTilePosition as soon as you are done using it, usually in the same file.

like image 102
Rob Avatar answered Oct 07 '22 22:10

Rob


Can you pass tileCoordinate as an argument to the function call? That way, the caller will find it easier to remember to malloc/calloc and free.

like image 39
vpit3833 Avatar answered Oct 07 '22 20:10

vpit3833


Very basic rule to follow is if you return a *malloc*ed pointer either give the user a function pass the pointer back to for freeing or document that you *malloc*ed it and that they should free it.

I've seen a variety of solutions to this (including full memory management abstraction) and personally I prefer the API designated free method since it is clear what to do when when it comes time to free the object and it gives the API a last attempt to do any additional clean up work.

like image 37
Andrew White Avatar answered Oct 07 '22 21:10

Andrew White


The caller will need to free the pointer malloced by your function.

However, if you package the tileForCoordinates function in a dynamic library, you should also provide an accompanying function for freeing the memory, and not have the caller do it. This is because the caller maybe be linking to the C runtime in a different manner than your library does. For instance, if your library statically links to the C runtime, while the caller links to it dynamically, or vice versa, having the caller free the memory will lead to crashes. In such cases you could provide a function similar to the following:

void freeTileCoordinates( CGPoint **tileCoordinate )
{
  // Also add additional checks for NULL pointer
  free( *tileCoordinate );
  *tileCoordinate = NULL;
}

Example usage:

CGPoint *point = tileForCoordinates( ... );

// use point
...

// now free it
freeTileCoordinates( &point );
like image 40
Praetorian Avatar answered Oct 07 '22 21:10

Praetorian