Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/68.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C:扫描期间的动态分配_C_Scanf_Dynamic Allocation - Fatal编程技术网

C:扫描期间的动态分配

C:扫描期间的动态分配,c,scanf,dynamic-allocation,C,Scanf,Dynamic Allocation,我想知道在使用scanf时/之前是否有任何方法可以动态分配一些内存。这意味着初始化时不需要给char*一个大小。相反,所需的内存量将根据输入字符串的大小进行分配(这意味着:拥有输入后) 目前,除了在输入之前分配特定数量的内存之外,我找不到其他解决方案,因此在知道输入的大小之前: char str[10]; scanf("%s", str); 我知道这是不安全的:如果输入超过10个字符,程序将在未分配的内存中写入,这可能会导致SEGFULT或类似的情况。使用该函数 ssize\u t getli

我想知道在使用scanf时/之前是否有任何方法可以动态分配一些内存。这意味着初始化时不需要给
char*
一个大小。相反,所需的内存量将根据输入字符串的大小进行分配(这意味着:拥有输入后)

目前,除了在输入之前分配特定数量的内存之外,我找不到其他解决方案,因此在知道输入的大小之前:

char str[10];
scanf("%s", str);
我知道这是不安全的:如果输入超过10个字符,程序将在未分配的内存中写入,这可能会导致SEGFULT或类似的情况。

使用该函数

ssize\u t getline(字符**lineptr,大小*n,文件*流);
示例

int main(无效)
{
字符*行;
大小;
if(getline(&line,&size,stdin)!=(-1))
{
printf(“您输入了:%s”,第行);
}
返回0;
}

正如评论中指出的,%m我相信可以解决您的问题

另一种方法是将输入限制为已知分配给变量的字节数,例如%10s将只输入10个字符
然后重新分配您的输入变量,以便在下次调用scanf时为输入更多字符腾出空间,您需要在下次调用中传递str like&str[10],以便它不会覆盖来自
stdin
的早期输入


OP的“如果输入长度超过10个字符,程序将在未分配的内存中写入”是一个关减1的问题。如果输入长度超过9,程序将尝试在
str[]
之外写入

char str[10];
scanf("%s", str);  // Trouble with input more than 9

getline(),这是典型的解决方案

我拒绝将“扫描期间的动态分配”作为一个好的设计目标。允许无休止输入的程序容易被滥用。它允许用户占用大量的系统资源好代码首先验证输入。没有了

相反,我建议对
stdin
输入进行评估,以确定合理的输入长度,可以是10、1000或1000000,并提供2倍左右的缓冲区

#define MAX_EXPECTED_SIZE 100
char buf[MAX_EXPECTED_SIZE * 2];
if (fgets(buf, sizeof buf, stdin)) {
  size_t len = strlen(buf);
  if (len + 1 == sizeof buf && buf[len] != '\n') {
    // Assume hostile input and act accordingly. Possibly exiting with message.
    // or consume rest of line
    int ch;
    while ((ch = getchar()) != '\n' && ch != EOF);

    return ERROR_LONG_LINE
  }

  // Use buf[]
}

如果需要保留buf的副本,Code可以在以后分配适当大小的内存。

是什么阻止了您编写一个完全满足您需要的函数?(另外,您对
str
的声明创建了一个由十个指针组成的数组,这可能不是您想要的。)首先不要使用
scanf
进行用户输入。不幸的是,我在这个主题上有点晚了,但您可以使用本手册。示例部分让您了解如何正确使用%m。请注意@melpomene注释,以了解您的libc版本可能存在的差异……您的
readLineString
不安全,并且使用长度为512的静态缓冲区。这在任何方面都不是动态的。(然后它会执行手动版本的
strdup
但这有什么用?@melpomene我同意,您如何使用动态长度读取输入?如果我感到懒惰,并且它不必是可移植的。@melpomene解决方案更改为使用
getline
now@nounoursnoir动态读取意味着您可以读取任意长度的行,如果
scanf
您需要类似
char buffer[512]
的内容,这意味着您最多只能从输入中读取512个字符,同样,恒定大小的缓冲区意味着它的大小是恒定的,而不是它的内容。数组是动态分配的这一事实并不意味着它的大小是由用户控制的。@woutrr With
getline()
程序的用户可以提供巨大的输入行-数十亿,强制代码分配巨大的内存资源——从而证明用户对程序有一定程度的控制——这是一种。
getline()
在设置了say 2K的上限时,不能防止滥用say“Enter your name”函数。底层操作系统可能会提供一些攻击检测,但不是必需的。@Wouterr“从而证明用户”->“从而提供用户”。