0

可能重复:
从 C 中的函数返回局部变量

我想得越多,我就越不确定为什么这不是一个好主意......编译器抱怨让函数内部的自动变量返回给调用者。例如:

char * foo() {
   char bar[11];
   fgets(bar, 10, stdin);
   return bar;
}

相对:

char bar[11];
char * foo() {
   fgets(bar, 10, stdin);
   return bar;
}

我可能没有多大意义。我不太明白在里面有一个指针声明的问题,调用者会不会只是假设内存地址?

4

3 回答 3

1

在您的第一个示例中,数组bar是函数的本地数组,因此当函数返回时它不再存在。因此,结果指针不太可能指向任何有用的东西,因为它曾经指向的东西不再存在。

于 2012-07-09T21:41:12.523 回答
0

第一个例子是完全错误的。您创建内存空间并在函数内部写入并返回指向它的指针,因此您将指针返回到不存在的内存段。从函数返回后,该内存将被释放。第二个例子是正确的,但你应该尽可能避免使用全局变量。

编辑:如果您希望内存在返回指针后在函数外部可用,请使用动态内存分配(检查calloc函数)。

于 2012-07-09T21:41:27.770 回答
0

bar,出于所有意图和目的,在您的函数返回时不再存在。它分配有自动存储持续时间,并且稍后尝试从该内存中读取会导致未定义的行为。由于通常使用堆栈,您如何想象在函数返回后将数据保持在有效状态?

相反,您可以将 achar*作为函数的输入,以及它所引用的内存块的大小,并为调用者填充该缓冲区,即:

void foo(char *buf, buf_size) {
   fgets(buf, buf_size, stdin);
}

这在 C 语言中非常常见和惯用。看看在fgets做什么。它要求调用者提供一个缓冲区来填充。这样可以避免混淆谁负责释放从函数返回的内存(如果函数返回指向动态分配的内存的指针,则必须记录下来)。

顺便说一句,fgets读取num-1字符并为您终止 null,因此只需传递缓冲区的大小,无需size-1像您当前所做的那样传递。

于 2012-07-09T21:41:35.273 回答