2013-02-14 129 views
4

这是作业分配的一部分。C返回字符[]警告“返回本地变量的地址”

我想在我的方法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空间,但是我们还没有在课堂上介绍过,即使我已经在另一课中做了一些。这真的是最好的方法吗?如果是这样,我可以在程序的任何地方释放吗?

+1

函数返回时局部变量不再存在,则返回一个悬挂指针。让我找到一个骗局。 – 2013-02-14 10:21:12

+0

如果要在堆上分配内存,请使用'malloc'。这个问题在这里已经被无数次地提出。 – KBart 2013-02-14 10:22:29

+0

这是很常见的错误,所以你肯定会发现几十篇有关遇到这个问题的文章:)其中一个原因是,大多数编译器甚至不会警告你你在做什么:http:// ideone。 com/S5Se71 – LihO 2013-02-14 10:32:47

回答

12

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

试图访问内存,该内存已被释放,导致未定义的行为

您可以动态地分配你的阵列,让来电者明确地释放它:

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

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

我应该制作一个这个答案的模板..;) – KBart 2013-02-14 10:24:39

4

替代不使用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 variablesfunction scope也保留其值。这个变量只有一个实例,每次调用该函数都会使用同一个变量(因此不能重新进入/线程安全)。程序启动时为静态变量分配内存,既不是堆栈也不是堆栈,但是它在运行程序内存空间时是自己的保留区域。静态变量的值在第一次使用之前被初始化一次(上面没有具体的初始化,所以它被填充0,但它也可以有一个初始化器,并且只有当函数被第一次调用时它才是值)。虽然以这种方式使用静态变量可能看起来有些不方便(我同意它),但它仍然是标准C所使用的有效模式,例如with strtok() function。它还表明需要一个可重入的版本,因为C标准也有strtok_r(),因为它有一个额外的参数,而不是其中的局部静态变量,所以使用起来更复杂。

相关问题