C:扫描期间的动态分配
我想知道在使用scanf时/之前是否有任何方法可以动态分配一些内存。这意味着初始化时不需要给C:扫描期间的动态分配,c,scanf,dynamic-allocation,C,Scanf,Dynamic Allocation,我想知道在使用scanf时/之前是否有任何方法可以动态分配一些内存。这意味着初始化时不需要给char*一个大小。相反,所需的内存量将根据输入字符串的大小进行分配(这意味着:拥有输入后) 目前,除了在输入之前分配特定数量的内存之外,我找不到其他解决方案,因此在知道输入的大小之前: char str[10]; scanf("%s", str); 我知道这是不安全的:如果输入超过10个字符,程序将在未分配的内存中写入,这可能会导致SEGFULT或类似的情况。使用该函数 ssize\u t getli
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 Withgetline()
程序的用户可以提供巨大的输入行-数十亿,强制代码分配巨大的内存资源——从而证明用户对程序有一定程度的控制——这是一种。getline()
在设置了say 2K的上限时,不能防止滥用say“Enter your name”函数。底层操作系统可能会提供一些攻击检测,但不是必需的。@Wouterr“从而证明用户”->“从而提供用户”。