[英]Does memory need to be allocated when reading input with getchar() in C?
在下面的代碼中,是否應該使用諸如malloc()
類的函數為指針c
分配內存? 我擔心增加c
可能導致它指向另一個變量,從而在*c = getchar()
被調用時覆蓋它。
char *c;
int count = 0;
while( (*c=getchar()) != '\n' ){
c++;
count++;
}
發布的代碼有問題:
c
是未初始化的,對其進行寫入具有立即未定義的行為,增加它只會使情況更糟。 c
是為了指向一個實際的數組,靜態,自動或動態地從堆與分配malloc()
您必須檢查c
保持在該數組的邊界內。 這是更正的版本:
#include <stdio.h>
int main() {
char buf[100];
int c, count, limit;
char *p;
p = buf; /* p points to an automatic array, no malloc needed */
count = 0;
limit = sizeof(buf) - 1; /* maximum number of characters to store */
while ((c = getchar()) != EOF && c != '\n') {
if (count < limit)
*p++ = c;
count++;
}
if (count < limit)
*p = '\0';
else
buf[limit] = '\0';
printf("%s\n", buf);
return 0;
}
這是帶有內存分配的一個:
#include <stdio.h>
#include <stdlib.h>
int main() {
char *buf, *p;
int c, count, limit;
limit = 99;
p = buf = malloc(limit + 1); /* p points to an array allocated from the heap */
count = 0;
if (buf == NULL) {
printf("allocation failure\n");
return 1;
}
while ((c = getchar()) != EOF && c != '\n') {
if (count < limit)
*p++ = c;
count++;
}
if (count < limit)
*p = '\0';
else
buf[limit] = '\0';
printf("%s\n", buf);
free(buf);
return 0;
}
筆記:
while ((c = getchar()) != EOF && c != '\\n')
是一個經典的C習慣用法,可從標准輸入中讀取一個字節,並將其存儲在int
變量c
,檢查是否為end文件,然后檢查用於單個控件表達式中的行尾。 &&
評估其左側,並且僅在無法從左側的值確定布爾類型0
或1
值int
的結果時才評估其右側。 這種特性稱為快捷方式評估 ,適用於||
和三元運算符?
/ :
也。 c
必須具有可以容納所有由getchar()
重新調整的值的類型:所有類型為unsigned char
和特殊負值EOF
值。 char
, signed char
和unsigned char
都不適合此操作,因為c == EOF
對於簽名char
情況將不正確地匹配\\377
(在ISO-8859-1中為'ÿ'
),或者對於unsigned char
情況將永遠不匹配。 int
是c
的正確類型。 是的 ,應該。
但是您實際上並不需要這里的指針。 getchar()
返回一個int
。
從文檔中我們可以看到getchar
的原型如下所示:
int getchar(void)
它不會返回指針,因此如果您要以某種方式使用指針,則必須確保它指向某個對象。 實際上,您的代碼會發出以下警告:
warning: assignment makes pointer from integer without a cast [-Wint-conversion]
while( (c=getchar()) != '\n' ){
^
您不必一定要使用malloc
本身,但是必須確保c
指向有效地址。 而且,由於您要遞增c
您還要負責確保這些地址有效。
簡短的回答:是的,需要分配內存。
而且它不只是getchar
- 任何時候你有一個像指針
char *c;
您必須謹慎考慮它指向的位置以及那里是否有已分配的內存。
實際上,如果您說的是
char *c;
您不知道指針c
指向哪里,因此您不知道那里是否有任何已分配的內存,但是如果我們不得不猜測,我們不得不說可能沒有。
話
char *c;
然后問指針c
指向哪里,就像在說
int i;
然后問什么
printf("%d\n", i);
將打印。 由於我們沒有將i
設置為任何值,因此我們不知道它將顯示什么。
如果您想讀取幾個字符,並將它們存儲在數組中,並使用指針來執行此操作,則可以-但是您需要分配數組,並使指針指向它。 它可能看起來像這樣。 順便說一下,在這一點上,我將指針變量的名稱更改為p
,這是指針的更常用名稱。 ( c
聽起來像一個字符,而不是一個指向字符的指針。)
char *p;
char arr[10];
int count = 0;
p = &arr[0];
while( (*p=getchar()) != '\n' ){
p++;
count++;
}
現在指針變量p
有指向的地方,因此使用它存儲*p=getchar()
字符是有效的。
話雖如此,我們有兩個很大的問題。 一種是將數組聲明為足以容納10個字符的大小,但是填充數組的循環不會對此進行檢查。 如果有人在按下Enter或Return鍵之前輸入10個或更多字符, p
就會離開為該數組分配的空間的結尾,並開始覆蓋其他內存,這是您擔心的。
第二個困難是我們不檢查文件結尾。 而且,我們無法正確檢查文件結尾,因為文件結尾指示符EOF
不是有效的字符值,因此無法放入*p
,后者只能容納字符值。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.