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 []警告“返回局部变量的地址”[重复]的主要内容,如果未能解决你的问题,请参考以下文章

错误:函数返回局部变量的地址

ranged for 变量循环导致返回局部变量的地址引用?

C语言基础:指针相关概念(指针的算术运算 指针数组指向指针的指针 传递指针给函数 从函数返回指针 )为啥C 语言不支持在调用函数时返回局部变量的地址?

C 从函数返回指针

C 从函数返回指针

直接使用运算符的地址与使用指针变量返回局部变量的地址