【问题标题】:memory allocation error with scanfscanf 内存分配错误
【发布时间】:2023-03-17 11:04:02
【问题描述】:

我有这个简单的代码,但不知道如何为 scanf 分配内存

char* string= (char*) malloc (sizeof(char));
printf("insert string: \n");
scanf("%s", string);
free(string);

不管我的字符串有多少个字符,这是一个错误。我想对 char* 使用 malloc,以任何方式为 scanf 设置内存。

【问题讨论】:

  • 您只为字符串分配 1 个字节。对于空字符串的字符串终止符\0 来说已经足够了,但仅此而已。
  • “这是一个错误”是什么意思? 什么错误?你如何分配多个字符?顺便说一句,sizeof(char) 被指定为始终导致1

标签: c memory memory-management valgrind scanf


【解决方案1】:

你只是请求 1 个字节。如果您想在字符串中存储的不仅仅是 0 终止符,则需要分配更多:

char* string= malloc (256); //256 bytes, arbitrary value...

我删除了:

  • sizeof(char),因为它始终保证为1
  • (char*) 因为转换了 malloc() is needless 的返回值。

我还建议使用fgets() 而不是scanf() 来防止缓冲区溢出。通过在格式字符串中指定长度,scanf() 也可以做到这一点。但我个人更喜欢使用fgets(),必要时使用sscanf() 进行解析。

【讨论】:

    【解决方案2】:

    试试

      char buf[256];
      scanf( "%s" , buf);
    

    删除你的 malloc。 您正在为可能是可变大小的字符串数组分配一小块内存。默认情况下,数组只是指向 buf[0] 的指针,这是字符串将给它的。您需要一个缓冲区来捕获初始读取,然后再分配适当的内存。

    之后你可以做 string = length(buf) * sizeof(char)

    分配正确的字符串长度。

    【讨论】:

      【解决方案3】:

      正如@Blue Moon 正确指出的那样,您只是分配内存来存储一个字符,单个字符可以存储的唯一字符串是空字符串或没有字符的字符串。在 C 中,所有字符串都以空字符结尾,您分配的 1 字节内存只能容纳空字符,即 '\0'

      为了在字符串中存储更多字符,比如一百个字符,您可以执行以下操作:

      #define MAX_STRING_SIZE 102
      
      char* string= (char*) malloc (sizeof(char) * MAX_STRING_SIZE);
      memset(string, '\0', MAX_STRING_SIZE);
      printf("Insert string: \n");
      scanf("%101s", string);
      if (strlen(string) == (MAX_STRING_SIZE - 1))
      {
          printf("The user entered a string larger than 100 characters!");
          free(string);
          /****Error handling***/
      }
      
      /*****Do something with string****/
      free(string)
      

      上面的 sn-p 是一个很好的小技巧,可以判断用户是否输入了有效数量的字符。如果您希望用户最多输入 100 个字符,并且您的程序始终在理想情况下运行(用户一直在听您的声音并且从不输入超过 100 个字符),您只需要一个额外的字节来存储 null特点。因此,您需要 101 个字符的空间。但是您可以为另一个字符添加空间,并分配 102 个字节来查找用户输入的字符串长度超过 100 个字符的情况。

      工作原理:假设用户输入了 100 多个字符。 scanf 函数最多可以读取 101 个字符。因此,我们可以使用strlen函数来检查用户输入的字符数是否等于101,这将有助于我们验证输入的字符串。

      【讨论】:

      • 你的意思是%101s。此外,最好检查 scanf 返回值或初始化字符串,以防 EOF 发生
      • @Matt McNabb:%101s 宽度说明符会将可读取的字符数限制为 101。我使用了另一个空格来保留空字符(第 102 个位置),以便 strlen 可以运行在保存的字符串上成功(因为 strlen 搜索空字符)。我添加了 memset 以将所有字符值设置为 '\0' 以使答案更完整:)
      • 再看sn-p后,我意识到calloc可以一步完成malloc + memset。它会让它看起来更整洁;)
      • 是的 %101s 会限制字符数,但您没有在代码中写下它。你写了101%s
      • “让它看起来更整洁” - char string[MAX_STRING_SIZE]; 会更好。
      猜你喜欢
      • 2020-04-21
      • 2011-07-07
      • 1970-01-01
      • 2016-10-29
      • 2021-04-15
      • 2012-11-27
      • 2010-12-08
      • 2011-12-21
      • 1970-01-01
      相关资源
      最近更新 更多