C返回char []警告“返回局部变量的地址”[重复]
Posted
技术标签:
【中文标题】C返回char []警告“返回局部变量的地址”[重复]【英文标题】:C Returning char[] Warning "returns address of local variable" [duplicate] 【发布时间】:2013-01-30 02:50:50 【问题描述】:这是家庭作业的一部分。
我试图在我的方法 getLine 中读取并返回文件的单行。
char *getLine(FILE *input)
char line[30];
if(fgets(line, sizeof(line), input)!=NULL)
return line;
else
return NULL;
根据我所学过的指针,这似乎可行,但是我无法删除警告消息warning: function returns address of local variable [enabled by default]
。此警告指的是return line;
行。我的任务要求我在编译时没有警告或错误。我看不出我做错了什么。
我找到的大部分帮助都建议为文本行分配 malloc-ing 空间,但我们还没有在课堂上介绍过,即使我在另一堂课上做过一些。这真的是最好的方法吗?如果是这样,我可以在程序的任何地方释放吗?
【问题讨论】:
函数返回时局部变量不复存在,然后返回一个悬空指针。让我找个骗子。 如果要在堆上分配内存,请使用malloc
。而这个问题已经在这里被问过无数次了。
这是一个很常见的错误,所以你肯定会发现很多关于遇到这个问题的帖子 :) 原因之一是大多数编译器甚至不会警告你你在做什么:ideone.com/S5Se71
这意味着你应该确切地知道你在做什么:)
所以这个问题是重复的吗?什么?
【参考方案1】:
char line[30];
是一个自动存储时长的数组。一旦执行超出您的函数范围,它所在的内存就会被释放,因此您返回的指向该内存的指针将变得无效(悬空指针)。
尝试访问已被释放的内存会导致未定义的行为。
您可以动态分配您的数组并让调用者显式释放它:
char *getLine()
char* line = malloc(30);
...
return line;
// somewhere:
char* line = getLine();
...
free(line);
【讨论】:
我应该制作这个答案的模板..;)【参考方案2】:不使用 malloc 的替代方案,据我所知,之前的问题并未涵盖:
/* Warning, this function is not re-entrant. It overwrites result of previous call */
char *getLine(FILE *input)
static char line[30];
return fgets(line, sizeof(line), input);
/* fgets returns NULL on failure, line on success, no need to test it */
解释:function scope 中的static variables 即使在函数返回后仍保留它们的值。这种变量只有一个实例,每次调用该函数时都使用相同的实例(因此不是可重入/线程安全的)。静态变量的内存是在程序启动时分配的,它既不是堆也不是堆栈,而是运行程序内存空间中自己的保留区域。静态变量的值在第一次使用之前只初始化一次(上面没有特定的初始化,所以用 0 填充,但它也可以有一个初始化器,这只是第一次调用函数时的值)。
虽然以这种方式使用静态变量可能看起来有点笨拙(我同意这一点),但它仍然是标准 C 所采用的有效模式,例如 with strtok()
function。它还表明需要一个可重入的版本,因为 C 标准也有 strtok_r()
,它使用起来更复杂,因为它有一个额外的参数,而不是其中包含局部静态变量。
【讨论】:
以上是关于C返回char []警告“返回局部变量的地址”[重复]的主要内容,如果未能解决你的问题,请参考以下文章
C语言基础:指针相关概念(指针的算术运算 指针数组指向指针的指针 传递指针给函数 从函数返回指针 )为啥C 语言不支持在调用函数时返回局部变量的地址?