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 *tileCoordin开发者_开发问答ate = (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? :)
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.
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.
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.
The caller will need to free
the pointer malloc
ed 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 );
As a rule, everything you malloc
you have to also free
. As another rule, if your api does the allocation, your api should ALSO do the deallocation, since at some future point down the road you may change the underlying mechanism. Also, in Windows, if memory is allocated by a DLL, it has to be freed by the same DLL or crashy things happen.
So, in general, the pattern looks like this:
MyType* foo = myapi_dosomething(x,y,z);
if (!foo) die("No Foo!");
use_object(foo);
myapi_free(foo);
foo=NULL; // just in case
精彩评论