簡體   English   中英

在scanf中使用malloc符合c ansi標准

[英]Is using malloc within scanf compliant to c ansi standard

我想閱讀用戶的輸入並保存。 我現在有什么工作,但我需要知道它是否合法(遵循ansi標准 - c90)scanf在為輸入分配內存之前首先分配變量“length”,或者它只是編譯器的一個怪癖。

#include <stdio.h>
int main()
{
    char* text;
    int length = 0;
    scanf("%s%n", text = malloc(length+1), &length);

    printf("%s", text);

    return 0;
}  

不會像你期望的那樣工作。

在調用malloclength仍然具有值0,因此您只分配一個字節。 scanf返回之前, length不會更新。 因此,任何非空字符串都將寫入已分配緩沖區的邊界,從而調用未定義的行為

雖然不完全相同 ,但你可以做的是使用getline ,假設你在一個POSIX系統上運行,比如Linux。 此函數讀取一行文本(包括換行符)並為該行分配空間。

char *text = NULL;
size_t n = 0;
ssite_t rval = getline(&text, &n, stdin);

if (rval == -1) {
    perror("getline failed");
} else {
    printf("%s", text);
}
free(text);

除了在另一個答案中解決了濫用scanf的明顯問題之外,這也不遵循任何C標准:

#include <stdio.h>
...
text = malloc(length+1)

由於你沒有包含stdlib.h ,其中找到malloc ,C90將假設函數malloc的形式為int malloc(int); 這當然是胡說八道。

然后,當您嘗試將一個int (malloc的結果)分配給char* ,您的約束違反了C90 6.3.16.1,即簡單賦值的規則。

因此,不允許您的代碼干凈地編譯,但編譯器必須提供診斷消息。

您可以通過升級到標准ISO C來避免此錯誤。

其他人解釋的問題很好

我想閱讀用戶的輸入並保存

要添加並滿足OP的目標,類似的代碼可以做到

int length = 255;
char* text = malloc(length+1);
if (text == NULL) {
  Handle_OOM();
} 
scanf("%255s%n", text, &length);

// Reallocate if length < 255 and/or 
if (length < 255) {
  char *t = realloc(text, length + 1);
  if (t) text = t;
} else {
  tbd(); // fail  when length == 255 as all the "word" is not certainly read.
}

如果過度投入被認為是敵對的,那么上述將是一種簡單的方法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM