这是家庭作业的一部分。
我正在尝试阅读并在我的方法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空间,但是我们还没有在课堂上讨论过这个问题,即使我已经在另一个类中完成了一些操作。这真的是最好的方法吗?如果是这样,我可以在该计划的任何地方免费吗?
答案 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()
,因为它有一个额外的参数而不是在其中有本地静态变量,所以使用起来更复杂。