This question already has an answer here:
#include <string.h>
#include<stdio.h>
#include<stdlib.h>
char *chktype(char *Buffer, int Size)
{
char *strng = "Content-Type: ";
int sz;
char *found = strstr (Buffer, strng);
char *found1 = strstr(found, "\r\n");
sz=strlen(found)-strlen(found1);
char type[sz];
strncpy(type, found1, sz-1);
return(type);
}
void main(){
char *buffer = "HTTP/1.1 200 OK\r\nDate: Tue, 25 Jun 2013 16:27:16
GMT\r\nExpires: -1\r\nCache-Control: private,
max-age=0\r\nContent-Type: text/html;
charset=UTF-8\r\nContent-Encoding: gzip\r\nServer:
gws\r\nX-XSS-Protection: 1; mode=block\r\nX-Frame-Options:
SAMEORIGIN\r\nTransfer-Encoding: chunked\r\n\r\n";
char *extension = chktype (buffer, sizeof(buffer));
printf("%s\r\n", extension);
}
This yields:
warning: function returns address of local variable [enabled by
default]
...and i can't figure out what is wrong here. When I run it, I expect the output to be text/html; charset=UTF-8
but its gibberish.
What does the warning mean exactly?
Quick/Hacky answer(?):
Make
into
Long answer: The error is pretty clear, you are returning the address of a variable that is going to be destroyed soon as the function returns. There are a couple of ways to get around this.
One easy way is to make type
static
, this would fix things, by making the type variable have a lifetime of the program, but this will mean that you cannot call it twice in a row, you need to print or copy the result before calling again.The other way, is to allocate memory for a
char
array within your function and hope that you remember tofree
it once you are done with it. If you don't you will have a memory leak. This does not suffer from the above disadvantage.You return
type
, which points to an array which had been allocated on the stack and is invalid after the functionchktype()
has returned.You might like to allocate the result on the heap, like this:
However, there is the need to
free()
the result after not needed anymore.The
chktype
function allocates memory for an automatic variable on the stack, and then returns the address of this variable (i.e., a pointer to this variable).The problem is that variables allocated on the stack are automatically destroyed whenever they go out of scope (i.e., control passes outside of the curly braces that define the function).
This means that you're essentially returning a pointer to an invalid memory location, which is bad news. In C-speak, it's undefined behavior. In practical speak, it results in bad output or perhaps even a crash.
The correct way to return a
char*
from a function is to allocate new memory from the heap using themalloc
(orcalloc
) function. That means that the caller of the function is going to be responsible for freeing the memory used by the returned value, otherwise your program will leak memory.(Always put this requirement into the documentation for your function! Even if "documentation" means a comment above the declaration.)
For example, change your code to look like this:
Now, in the caller of the
chktype
function, you must make sure that you callfree
whenever you are finished with its return value:Note that robust code should test the result of
malloc
for a null pointer to make sure that it did not fail to allocate the requested memory. If so, you need to handle the error somehow. For clarity, that isn't shown above.When you declare
type
aschar type[sz]
, that's giving you a local variable. The lifetime of that memory will end when the function returns. Instead, you need to dynamically allocate memory, for example, usingmalloc
.