C返回char []警告“返回局部变量的地址”

时间:2013-02-14 10:19:49

标签: c pointers return compiler-warnings

这是家庭作业的一部分。

我正在尝试阅读并在我的方法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空间,但是我们还没有在课堂上讨论过这个问题,即使我已经在另一个类中完成了一些操作。这真的是最好的方法吗?如果是这样,我可以在该计划的任何地方免费吗?

2 个答案:

答案 0 :(得分:14)

char line[30];是一个具有自动存储持续时间的数组。一旦执行超出函数范围,它所驻留的内存就会被释放,因此返回的指向该内存的指针变为无效(悬空指针)。

尝试访问已经解除分配的内存会导致未定义的行为

您可以动态分配数组并让调用者显式释放它:

char *getLine() {
    char* line = malloc(30);
    ...
    return line;
}

// somewhere:
char* line = getLine();
...
free(line);

答案 1 :(得分:5)

不使用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 */
}

说明:static variables中的function scope即使在函数返回后也会保留其值。只有这样一个变量的一个实例,每次调用该函数时都使用相同的一个(因此不能重入/线程安全)。程序启动时会分配静态变量的内存,既不是堆也不是堆栈,而是在运行程序的内存空间中它自己的保留区域。在第一次使用之前,静态变量的值只被初始化一次(上面没有特定的初始化,所以它用0填充,但它也可以有一个初始化器,并且只有在第一次调用函数时才是它的值)。

虽然以这种方式使用静态变量可能看起来有点hacky(我同意它),但它仍然是标准C使用的有效模式,例如with strtok() function。它还表明需要一个可重入的版本,因为C标准也有strtok_r(),因为它有一个额外的参数而不是在其中有本地静态变量,所以使用起来更复杂。