提问人:Sai Surisetti 提问时间:9/1/2022 最后编辑:Sai Surisetti 更新时间:9/1/2022 访问量:56
在函数中调用 char* var (假设全局访问) = fgets(..) 后,var 中的值在从 main 调用函数后意外更改
After invoking char* var (assume global access) = fgets(..) inside a function, the value inside var changes unexpectedly after function call from main
问:
[编辑:显然,从fgets获得的返回值只是正在使用的char buffer[SIZE]的地址,所以在我的情况下,这是有道理的,因为我在本地声明了它(因此,块范围)。PS:感谢所有的帮助!
我只是倾向于,一旦编译器完成执行调用 fgets 的函数,fgets 存储的数据就不会保持不变。
这背后的原因是什么?fgets 的返回数据是否有寿命或其他东西?如果是这样,他们是如何编写诸如 fgets 之类的函数的?有什么东西可以跟踪用户的调用范围?
代码如下:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define SIZE 10
void input_string (char** pptr_one, char** pptr_two)
{
char buffer[SIZE];
printf("\nInput: ");
char* x = fgets(buffer, SIZE, stdin);
//Copying the original fgets result address:
*pptr_one = x;
//Copying its contents to another variable:
*pptr_two = malloc(SIZE);
strcpy(*pptr_two, x);
}
int main (int argc, char **argv)
{
char* ptr_one;
char* ptr_two;
input_string(&ptr_one, &ptr_two);
printf("\nptr_one is pointing to: <%s>\n", ptr_one);
printf("ptr_two is pointing to: <%s>\n", ptr_two);
return 0;
}
答:
您(间接)设置为 的地址,该地址在结束时停止存在。*pptr_one
buffer
input_string
没什么特别的;它只是返回它关于成功的第一个参数,在本例中是 ;之后,所有内存都指向函数本地的同一段内存。fgets
buffer
x
*pptr_one
评论
fgets
返回成功时的第一个参数或失败时的空指针;返回值允许您检查它是成功还是失败(您应该检查)。为什么第一个参数而不是其他非空参数?很难说,但有时很方便。(char *)1
缓冲区具有自动存储持续时间。char buffer[SIZE]
这意味着在函数返回后,与之关联的内存将被释放,并且由于它是局部变量而不再存在。input_string()
buffer
buffer
溶液:
您可以使用以下命令分配内存:buffer
malloc()
char *buffer = malloc(sizeof(char) * SIZE)
或者您可以声明为:buffer
static
static char buffer[SIZE];
void input_string (char** pptr_one, char** pptr_two)
{
char buffer[SIZE];
printf("\nInput: ");
char* x = fgets(buffer, SIZE, stdin);
// missing test for NULL return from fgets()
/*** DO NOT DO THIS.
* DO NOT TAKE THE ADDRESS OF A LOCAL VARIABLE FOR USE AFTER FUNCTION EXITS!
* When successful, fgets will return the address of 'buffer' so x points to buffer.
//Copying the original fgets result address:
*pptr_one = x;
*****/
//Copying its contents to another variable:
*pptr_two = malloc(SIZE);
// should check that malloc succeeded
strcpy(*pptr_two, x);
// Aren't you glad that fgets() guarantees buffer will be a null terminated string?
// Be sure caller free's the allocated piece of heap storage!
}
或者,如果您想使用该信息,请使缓冲区静态...
static char buffer[SIZE];
printf("\nInput: ");
如果使用静态内存块,请勿释放地址。
回顾 OP,您写道:“我刚刚了解到 fgets 存储的数据doesn't stay the same once the ... [execution of] the function in which fgets is being invoked.
"
所有数据都有持续时间。有些是磁盘上文件的持续时间,有些是程序执行的整个持续时间,有些是函数调用的短暂持续时间。
你的“缓冲区”在结束时蒸发并返回到它的调用函数('main()')。挂住数据的另一种方法是定义数据,并将缓冲区及其长度传递给 。input_string()
main()
input_string()
void input_string( char *buf, size_t len ) {
fgets(buffer, len, stdin);
}
int main() {
char buffer[ SIZE ];
input_string( buffer, sizeof buffer );
printf( "Got '%s' from stdin\n", buffer );
}
以上,完成,但数据仍然可用。input_string()
评论
static
:-)
评论
fgets()
goto