在c中使用realloc()代替固定长度缓冲区?

问题描述 投票:0回答:1

我编写了一些代码,在内存使用方面尽可能保守,因此它会使用

realloc()
一次构建一个字符的字符串,而不是像常见的那样使用一次性固定长度缓冲区。我认为这样做的好处是,在重要的环境中,您永远不会过度使用内存,并且您不必担心缓冲区对于极端情况来说太小,也不必编写一些
realloc()
代码来覆盖它。 我的问题是这是否会严重破坏内存或可能导致任何其他问题,或者编译器是否会优化它。

这是一个示例程序,它不使用固定长度的缓冲区来读取文本文件,并且运行良好。你为什么会或不会编写这样的代码?这显然是一个坏主意吗?

// Compile with: gcc a.c -o a
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char* argv[]) {

  void *tmp;
  char **array = NULL; // array of line strings
  size_t len = 0; // length of a line
  int i = 0; // line count

  // Open file
  FILE* f;
  if (!(f = fopen("./test.txt", "r"))) {
    printf("Err: open file\n");
    return 1;
  }

  // Read file into memory
  char chr;
  while ((chr = fgetc(f)) != EOF) {
    // Reserve mem for another line
    if (len == 0) {
      // add 2 -- 1 for null terminator, 1 cuz i starts at 0
      if ((tmp = realloc(array, (i+2)*sizeof(*array))) == NULL) {
        printf("Err: realloc\n");
        return 1;
      }
      array = tmp;
      array[i] = NULL;
      array[i+1] = NULL;
    }

    // Increase mem for next char in the line
    // add 2 -- 1 for null terminator, 1 cuz len starts at 0
    // Q: Why is best practice to omit sizeof knowing that for char it is always 1... all other alloc's need to use sizeof so the inconsistency leads to mistakes
    if ((tmp = realloc(array[i], (len+2)*sizeof(*(array[i])))) == NULL) {
    // if ((tmp = realloc(array[i], len+2)) == NULL) {
      printf("Err: realloc\n");
      return 1;
    }
    array[i] = tmp;
    array[i][len] = chr;
    array[i][len+1] = '\0';
    len++;

    // newline
    if (chr == '\n') {
      len = 0;
      i++;
    }
  }

  if (ferror(f)) {
    printf("Err: read file\n");
    return 1;
  }

  // Verify input
  printf("\nRead:\n-----\n");
  for (i=0; array[i] != NULL; i++) { // array is NULL terminated
    printf("[%d] %s", i+1, array[i]);
    free(array[i]);
  }
  free(array);

  printf("\nDone\n");
  fclose(f);
  return 0;
}
c memory-management buffer dynamic-memory-allocation realloc
1个回答
0
投票

当你第一次调用

malloc()
realloc()
时,他会分配一大块内存。这是为了将来的调用,而不是在每次使用时都要求更多的内存。

realloc()
在一切之前,先看看分配的块后面,看看他是否可以用一些可用空间来扩展该块。如果他不能,他会为您
malloc()
提供一个新的记忆空间。 这是一个很好的策略,但在你的情况下效果不太好。

这里的问题是你

realloc()
多个指针,所以你的内存看起来一团糟,你只是创建了一些碎片。

另一件事,现在的内存真的很便宜,你可以分配更多。 与 C++ 容器实现相比,它们分配了所需的空间 * 2,以提高性能。 您会因所有

realloc()
电话而浪费很多时间。

© www.soinside.com 2019 - 2024. All rights reserved.