Is it good practice to return pointer from function in c?
For Ex:
int *point() {
int *q = malloc(sizeof(int));
*q=20;
return q;
}
int main() {
int *a = point();
free(a);
}
I wonder if this is a good p开发者_StackOverflow社区ractice in c?
Returning pointers is quite common. The problem, or discipline needed, is to be sure where the responsibility of freeing memory lies. This example smells because it's not clear that it needed to be free'd in main().
I think the problem is the free(a); I think you should add a release_point() function.
Check out the C example on the wikipedia page for opaque pointers. It's a way of structuring code where you manage the memory fully on one side of the interface.
The only real danger I know of with returning a pointer to allocated memory is this: If your library is compiled on Windows and linked to one instance of the Visual C++ runtime library (MSVCRT), for example, it is statically linked to it, and a client program is linked to another instance, for example, it is linked to the DLL, then they each have a different malloc arena, and pointers returned by the library cannot be freed by the program. Any attempt to do so is likely to cause the program to crash.
I would advocate always having your own function to free memory that is returned by your library, unless you are returning something trivial such as a string.
The reason for this is that, if you change the structure of what you are returning such that a simple free
will no longer be enough (because you add to the returned object pointers to allocated memory that themselves need to be freed), clients will not need to change their code; you can just change your existing free function.
So having your own free function insulates clients from the structure of objects returned by your library, leaving you free to change the structure of your objects without affecting clients.
If you have a consistent system of knowing which functions return pointers that must be freed (such as using the word create
or new
in the function's name) then it makes it easier to manage your memory.
int *createPoint()
{
int *q = malloc(sizeof(int));
if (*q)
*q = 20;
return q;
}
It's often good practice, but your example is one of the few cases where it's very bad practice. You should never use dynamic allocation and pointers for individual objects which are small and do not contain (and will never need to contain) pointers themselves. Obtaining a 4-byte int
with malloc
uses at least 16 bytes once you factor in bookkeeping overhead, but perhaps much more importantly, it means you have to worry about possible allocation failures (and how to handle them) and managing when to free the object.
Some examples of objects you shouldn't be allocating like this:
- any basic type
- ordered pairs/coordinates/vectors/matrices/etc. (as long as they're fixed-dimension)
- ip addresses
- color values
Of course the one time it might make sense to allocate and return a pointer to such objects is when you're allocating an array of them.
精彩评论