C语言 警告:函数返回局部变量的地址[默认启用]
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17312336/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
warning: function returns address of local variable [enabled by default]
提问by aDi Adam
#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-8but its gibberish.
......我无法弄清楚这里出了什么问题。当我运行它时,我希望输出text/html; charset=UTF-8只是乱码。
What does the warning mean exactly?
警告究竟是什么意思?
回答by Cody Gray
The chktypefunction allocates memory for an automatic variable on the stack, and then returns the address of this variable (i.e., a pointer to this variable).
该chktype函数为堆栈上的自动变量分配内存,然后返回该变量的地址(即指向该变量的指针)。
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.
这意味着您实际上是在返回一个指向无效内存位置的指针,这是个坏消息。在 C 语言中,它是未定义的行为。实际上,它会导致输出不佳甚至崩溃。
char *chktype(char *Buffer, int Size)
{
// This pointer variable is allocated on the stack, but that's okay because
// it's a pointer to a string literal, which are always constant.
// (Technically, you should add the "const" qualifier to the declaration.)
const char *strng = "Content-Type: ";
int sz;
char *found = strstr (Buffer, strng);
char *found1 = strstr(found, "\r\n");
sz=strlen(found)-strlen(found1);
// Like all the above variables, the one is also allocated on the stack.
// But it's the source of your problem here, because it's the one that
// you are returning at the end of the function.
// Problem is, it goes away at the end of the function!
char type[sz];
strncpy(type, found1, sz-1);
return(type);
}
The correct way to return a char*from a function is to allocate new memory from the heap using the malloc(or calloc) function. That means that the callerof 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.)
char*从函数返回 a 的正确方法是使用malloc(or calloc) 函数从堆分配新内存。这意味着函数的调用者将负责释放返回值使用的内存,否则您的程序将泄漏内存。
(始终将此要求放入您的函数的文档中!即使“文档”表示声明上方的注释。)
For example, change your code to look like this:
例如,将您的代码更改为如下所示:
char *chktype(char *Buffer, int Size)
{
// This pointer variable is allocated on the stack, but that's okay because
// it's a pointer to a string literal, which are always constant.
// (Technically, you should add the "const" qualifier to the declaration.)
const char *strng = "Content-Type: ";
int sz;
char *found = strstr (Buffer, strng);
char *found1 = strstr(found, "\r\n");
sz=strlen(found)-strlen(found1);
char *type = malloc(sz); // allocate memory from the heap
strncpy(type, found1, sz-1);
return(type);
}
Now, in the caller of the chktypefunction, you must make sure that you call freewhenever you are finished with its return value:
现在,在chktype函数的调用者中,您必须确保free在完成其返回值时调用:
char *type = chktype(...);
// do something
free(type);
Note that robust code should test the result of mallocfor 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.
请注意,健壮的代码应该测试malloc空指针的结果,以确保它没有未能分配请求的内存。如果是这样,您需要以某种方式处理错误。为清楚起见,上面没有显示。
回答by Karthik T
Quick/Hacky answer(?):
快速/骇人听闻的答案(?):
Make
制作
char type[sz];
into
进入
static char type[sz];
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.
一种简单的方法是使 type static,这可以解决问题,通过使 type 变量具有程序的生命周期,但这将意味着您不能连续调用它两次,您需要在再次调用之前打印或复制结果.
The other way, is to allocate memoryfor a chararray within your function and hope that you remember to freeit once you are done with it. If you don't you will have a memory leak. This does not suffer from the above disadvantage.
另一种方法是在你的函数中为数组分配内存,char并希望free你在完成后记住它。如果你不这样做,你就会有内存泄漏。这不会受到上述缺点的影响。
回答by Keith
When you declare typeas char 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, using malloc.
当你声明type的char type[sz],这是给你一个局部变量。当函数返回时,该内存的生命周期将结束。相反,您需要动态分配内存,例如,使用malloc.
char *type = (char *) malloc (sz * sizeof (char));
回答by alk
You return type, which points to an array which had been allocated on the stack and is invalid after the function chktype()has returned.
您 return type,它指向一个已在堆栈上分配且在函数chktype()返回后无效的数组。
You might like to allocate the result on the heap, like this:
您可能希望在堆上分配结果,如下所示:
char * chktype(const char * buffer, int size)
{
char * strng = "Content-Type: ";
char * found = strstr (buffer, strng);
char * found1 = strstr(found, "\r\n");
size_t sz = strlen(found) - strlen(found1);
char * type = calloc(sz, sizeof(*type));
if (type)
{
strncpy(type, found1, sz - 1);
}
return type;
}
However, there is the need to free()the result after not needed anymore.
然而,free()在不再需要之后需要结果。

