![](/img/trans.png)
[英]Char array being cleared after unrelated function call to fgets?
[英]After invoking char* var (assume global access) = fgets(..) inside a function, the value inside var changes unexpectedly after function call from main
[編輯:顯然從 fgets 獲得的返回值只是正在使用的 char 緩沖區 [SIZE] 的地址,所以在我的情況下這是有道理的,因為我在本地聲明了它(因此,塊范圍).. PS:感謝所有幫助!]
我只是傾向於一旦編譯器執行完調用 fgets 的 function,fgets 存儲的數據就不會保持不變。
這背后的原因是什么? fgets 的返回數據是否有生命周期之類的? 如果是這樣,他們甚至是如何編寫諸如 fgets 之類的 function 的? 可以跟蹤用戶調用 scope 的東西嗎?
這是代碼:
#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;
}
您的緩沖區char buffer[SIZE]
具有自動存儲持續時間。
這意味着在 function input_string()
返回后,與buffer
關聯的 memory 將被釋放,並且buffer
將不復存在,因為它是一個局部變量。
解決方案:
您可以使用malloc()
為buffer
分配 memory :
char *buffer = malloc(sizeof(char) * SIZE)
或者您可以將buffer
聲明為static
:
static char buffer[SIZE];
您(間接)將*pptr_one
設置為buffer
的地址,當input_string
結束時該地址停止存在。
fgets
沒有什么特別之處; 它只是在成功時返回它的第一個參數,在這種情況下是buffer
; 之后, x
和*pptr_one
都指向 function 本地的同一塊 memory。
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...
static char buffer[SIZE];
printf("\nInput: ");
如果使用 memory 的 static 塊,請勿釋放地址。
查看 OP,您寫道:“我剛剛了解到 fgets 存儲的數據doesn't stay the same once the... [execution of] the function in which fgets is being invoked.
”
所有數據都有一個持續時間。 有些是磁盤上文件的持續時間,有些是程序執行的整個持續時間,有些是 function 調用的短暫持續時間。
當input_string()
結束並返回到它的調用 function ('main()') 時,你的“緩沖區”消失了。 掛在數據上的另一種方法是在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()
完成了,但數據仍然可用。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.