aDi*_*dam 5 c dynamic-allocation
#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);
}
Run Code Online (Sandbox Code Playgroud)
这会产生:
warning: function returns address of local variable [enabled by
default]
Run Code Online (Sandbox Code Playgroud)
......我无法弄清楚这里有什么问题.当我运行它时,我希望输出text/html; charset=UTF-8只是它的胡言乱语.
警告到底意味着什么?
Cod*_*ray 14
该chktype函数为堆栈上的自动变量分配内存,然后返回此变量的地址(即指向此变量的指针).
问题是堆栈上分配的变量会在超出范围时自动销毁(即控制传递到定义函数的花括号之外).
这意味着你实际上是在返回一个指向无效内存位置的指针,这是个坏消息.在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);
}
Run Code Online (Sandbox Code Playgroud)
char*从函数返回a的正确方法是使用malloc(或calloc)函数从堆中分配新内存.这意味着该函数的调用者将负责释放返回值使用的内存,否则您的程序将泄漏内存.
(始终将此要求放入函数的文档中!即使"文档"表示声明上方的注释.)
例如,将代码更改为如下所示:
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);
}
Run Code Online (Sandbox Code Playgroud)
现在,在chktype函数的调用者中,您必须确保free在完成其返回值时调用:
char *type = chktype(...);
// do something
free(type);
Run Code Online (Sandbox Code Playgroud)
请注意,健壮的代码应测试malloc空指针的结果,以确保它无法分配所请求的内存.如果是这样,您需要以某种方式处理错误.为清楚起见,上面没有显示.
快速/ Hacky答案(?):
使
char type[sz];
Run Code Online (Sandbox Code Playgroud)
成
static char type[sz];
Run Code Online (Sandbox Code Playgroud)
答案很长:错误非常明显,您将返回一个变量的地址,该变量将在函数返回时立即销毁.有几种方法可以解决这个问题.
一种简单的方法是static通过使类型变量具有程序的生命周期来创建类型,这将解决问题,但这意味着您不能连续两次调用它,您需要在再次调用之前打印或复制结果.
另一种方法是为你的函数中的数组分配内存,char并希望你完成后记住free它.如果不这样做,您将有内存泄漏.这不会受到上述缺点的影响.