【问题标题】:C - realloc error: corrupted size vs prev_sizeC - realloc 错误:损坏的大小与 prev_size
【发布时间】:2018-01-09 22:48:27
【问题描述】:

有人能解释一下这个错误吗?
我收到了错误,直到一时兴起,我改变了这一行:

char *tmp = realloc(str, sizeof(char)*length);
// to                                           added 1
char *tmp = realloc(str, sizeof(char) * length + 1);

我认为将sizeof(char) 乘以长度会重新分配size=sizeof(char)*length 的新内存区域。我不明白为什么添加 1 可以解决问题。

    void edit_print(char *inputStr, size_t space_size) {
      size_t ch_position = 0;
      size_t space_column_count = 0;
      size_t num_spaces_left = 0;
      while ((inputStr[ch_position] != '\0')) {
        if ((inputStr[ch_position] == '\t') && (space_size !=0)) {
          num_spaces_left = (space_size-(space_column_count % space_size));
          if (ch_position == 0 || !(num_spaces_left)) {
            for (size_t i=1; i <= space_size; i++) {
              putchar(' ');
              space_column_count++;
            }
            ch_position++;
          } else {
            for (size_t i=1; i <= num_spaces_left; i++) {
              putchar(' ');
              space_column_count++;
            }
            ch_position++;
          }
        } else {
          putchar(inputStr[ch_position++]);
          space_column_count++;
        }
      }
      printf("\n");
    }

        int main(int argc, char *argv[]) {
          size_t space_size_arg = 3; 
          int inputch;
          size_t length = 0;
          size_t size = 10;
          char *str = realloc(NULL, sizeof(char) * size);
          printf("Enter stuff\n");

          while ((inputch = getchar()) != EOF) {
            if (inputch == '\n') {
              str[length++] = '\0';

              //changed line below
              char *tmp = realloc(str, sizeof(char) * length + 1);

              if (tmp == NULL) {
                exit(0);
              } else {
                str = tmp;
              }
              edit_print(str, space_size_arg);
              length = 0;
            } else {
              str[length++] = inputch;
              if (length == size) {
                char *tmp = realloc(str, sizeof(char) * (size += 20));
                if (tmp == NULL) {
                  exit(0);
                } else {
                  str = tmp;
                }
              }
            }
          }
          free(str);
          return 0;
        }

编辑:我最初收到的错误消息是这篇文章标题中的错误消息。进行chux建议的更改后,错误为“realloc(): invalid next size: *hexnumber**”

【问题讨论】:

  • 建议让我们了解“错误”可能有助于找出问题所在。
  • 我的猜测:edit_print 包含缓冲区溢出错误。你通过给它一些额外的空间来掩盖这个错误。
  • OT:这并不能解释错误,但 sizeof(char) * length + 1 在语义上是不正确的。 sizeof() 应该乘以 length + 1 的总和。但是因为,在这种情况下,sizeof(char)==1 --> 没问题。
  • 首先,“sizeof(char)”被定义为1,所以到处都是无关紧要和多余的。然后,似乎对您分配的所有这些内存执行任何操作的唯一代码是 edit_print(),您没有向我们展示。
  • @LeeDanielCrocker 我添加了函数

标签: c memory-management malloc realloc


【解决方案1】:

size 需要在inputch == '\n' 时更新。

char *tmp = realloc(str, sizeof(char) * length + 1 /* or no +1 */); 可以缩小分配。这使得后来的if (length == size) 无效(真正的分配大小更小),因此str[length++] = inputch; 失去了内存访问保护。更新 size 以修复该漏洞。

+1 不需要 - 它只是隐藏了问题,因为 + 1 并没有缩小分配。

  char *tmp = realloc(str, sizeof(char) * length);
  if (tmp == NULL) {
    exit(0);
  } else {
    str = tmp;
  }
  size = length; // add

关于sizeof(char)* 代码。按目标类型的大小进行缩放的想法很好,但对于 char,它并不重要,因为它总是 1. @Lee Daniel Crocker

如果代码想反映目标的类型可能会改变,不要使用size(the_type),使用sizeof(*the_pointer)。更易于编码、审查和维护。

// Don't even need to code the type `str` points to
tmp = realloc(str, sizeof *str * length);

【讨论】:

  • 很遗憾,您的建议并未解决该错误。我将编辑我的帖子以包含我所看到的内容。我还添加了edit_print。感谢您提供有关 sizeof(type) 的信息。
  • 请提供A Minimal, Complete, and Verifiable example 以获得进一步帮助。
  • @chux 添加 fprintf 后,最后几行:##### ####### ####### ###### # ###### # ###### 100 0x55da9f4416a0 41 # # # # # # # # # # # # 100 0x55da9f4416a0 41 # # # # # # # # # # # 100 0x55da9f4416a0 44 *** `./project1 中的错误':损坏的大小与 prev_size:0x000055da9f4416c0 *** 中止(核心转储)
  • fprintf(stderr, "%d %p %zu\n", LINE, (void*)str, sizeof(char)*length+1); @chux
  • @rhoward207 请注意,问题出现在第一个非空行比之前的行短。当然,问题在于缩小分配。 100 是可疑的,因为没有一行长度超过 75 个字符 - 嗯。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-05-23
  • 1970-01-01
  • 2018-09-12
  • 2018-01-23
  • 1970-01-01
  • 2018-12-15
  • 2021-08-20
相关资源
最近更新 更多