my function:
struct hostent * gethost(char * hostname){
if(/*some condition under which I want
to change the mode of my program to not take a host*/){
开发者_开发知识库 return null
}
else{
struct hostent * host = gethostbyname(hostname);
return host;
}
}
in main:
struct hostent * host = gethost(argv[2]);
(ignore any minor errors in the code, I'm spewing from memory)
this works fine. and Valgrind doesn't tell me I'm losing memory, despite the fact I'm not freeing.
Why? I thought stuff allocated on the stack disappears with the function call returning? or is it because I return the pointer? is this dangerous in any way?
host
is not allocated on the stack, only a pointer to it is on the stack. The pointer gets copied when the function returns, so there is nothing wrong with the code.
Note that gethostbyname
does not actually dynamically allocate memory. It always returns a pointer to the same statically allocated block of memory, which is why valgrind doesn't report a leak. Be careful, though, because that means you have to copy the hostent
returned by your function if you want to save the value for later because further calls to gethost
will overwrite it.
It's fine and does leak because the returned pointer doesn't point to data on stack or heap, but some static variable.
http://linux.die.net/man/3/gethostbyname:
The functions gethostbyname() and gethostbyaddr() may return pointers to static data, which may be overwritten by later calls. Copying the struct hostent does not suffice, since it contains pointers; a deep copy is required.
from the manual :
RETURN VALUE
The gethostbyname() and gethostbyaddr() functions return the hostent
structure or a NULL pointer if an error occurs. On error, the h_errno
variable holds an error number. When non-NULL, the return value may
point at static data, ...
Some memory is reserved at the compile time (ie. inside the binary the code) for the structure, the function returns a pointer to this memory.
Well the memory is not leaked until all references to it is lost, in your example the pointer is returned so there is still a reference to it.
However imho it's a bad design decision on most cases to rely on another part of the code to release dynamic memory. If the function needs to return a struct for example, the caller should do it and pass a pointer to the struct.
精彩评论